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
;
164 static struct reg_info reg_info_table
[] = {
175 static struct storage hardreg_storage_table
[] = {
178 .reg
= ®_info_table
[0],
183 .reg
= ®_info_table
[1],
188 .reg
= ®_info_table
[2],
193 .reg
= ®_info_table
[3],
198 .reg
= ®_info_table
[4],
203 .reg
= ®_info_table
[5],
208 .reg
= ®_info_table
[6],
213 .reg
= ®_info_table
[7],
217 #define REG_EAX (&hardreg_storage_table[0])
218 #define REG_ECX (&hardreg_storage_table[1])
219 #define REG_EDX (&hardreg_storage_table[2])
220 #define REG_ESP (&hardreg_storage_table[3])
221 #define REG_DL (&hardreg_storage_table[4])
222 #define REG_DX (&hardreg_storage_table[5])
223 #define REG_AL (&hardreg_storage_table[6])
224 #define REG_AX (&hardreg_storage_table[7])
227 static void emit_move(struct storage
*src
, struct storage
*dest
,
228 struct symbol
*ctype
, const char *comment
);
229 static int type_is_signed(struct symbol
*sym
);
230 static struct storage
*x86_address_gen(struct expression
*expr
);
231 static struct storage
*x86_symbol_expr(struct symbol
*sym
);
232 static void x86_symbol(struct symbol
*sym
);
233 static struct storage
*x86_statement(struct statement
*stmt
);
234 static struct storage
*x86_expression(struct expression
*expr
);
237 static struct storage
*temp_from_bits(unsigned int bit_size
)
240 case 8: return REG_AL
;
241 case 16: return REG_AX
;
242 case 32: return REG_EAX
;
253 static inline unsigned int pseudo_offset(struct storage
*s
)
255 if (s
->type
!= STOR_PSEUDO
)
256 return 123456; /* intentionally bogus value */
261 static inline unsigned int arg_offset(struct storage
*s
)
263 if (s
->type
!= STOR_ARG
)
264 return 123456; /* intentionally bogus value */
266 /* FIXME: this is wrong wrong wrong */
267 return current_func
->stack_size
+ ((1 + s
->idx
) * 4);
270 static const char *pretty_offset(int ofs
)
272 static char esp_buf
[64];
275 sprintf(esp_buf
, "%d(%%esp)", ofs
);
277 strcpy(esp_buf
, "(%esp)");
282 static void stor_sym_init(struct symbol
*sym
)
284 struct storage
*stor
;
285 struct symbol_private
*priv
;
287 priv
= calloc(1, sizeof(*priv
) + sizeof(*stor
));
289 die("OOM in stor_sym_init");
291 stor
= (struct storage
*) (priv
+ 1);
294 stor
->type
= STOR_SYM
;
298 static const char *stor_op_name(struct storage
*s
)
300 static char name
[32];
304 strcpy(name
, pretty_offset((int) pseudo_offset(s
)));
307 strcpy(name
, pretty_offset((int) arg_offset(s
)));
310 strcpy(name
, show_ident(s
->sym
->ident
));
313 strcpy(name
, s
->reg
->name
);
316 sprintf(name
, "$%Ld", s
->value
);
319 sprintf(name
, "%s.L%d", s
->flags
& STOR_LABEL_VAL
? "$" : "",
323 sprintf(name
, "%s.LS%p", s
->flags
& STOR_LABEL_VAL
? "$" : "",
331 static struct atom
*new_atom(enum atom_type type
)
335 atom
= calloc(1, sizeof(*atom
)); /* TODO: chunked alloc */
344 static inline void push_cstring(struct function
*f
, struct string
*str
,
349 atom
= new_atom(ATOM_CSTR
);
353 add_ptr_list(&f
->str_list
, atom
); /* note: _not_ atom_list */
356 static inline void push_atom(struct function
*f
, struct atom
*atom
)
358 add_ptr_list(&f
->atom_list
, atom
);
361 static void push_text_atom(struct function
*f
, const char *text
)
363 struct atom
*atom
= new_atom(ATOM_TEXT
);
365 atom
->text
= strdup(text
);
366 atom
->text_len
= strlen(text
);
371 static struct storage
*new_storage(enum storage_type type
)
373 struct storage
*stor
;
375 stor
= calloc(1, sizeof(*stor
));
377 die("OOM in new_storage");
384 static struct storage
*stack_alloc(int n_bytes
)
386 struct function
*f
= current_func
;
387 struct storage
*stor
;
391 stor
= new_storage(STOR_PSEUDO
);
392 stor
->type
= STOR_PSEUDO
;
393 stor
->pseudo
= f
->pseudo_nr
;
394 stor
->offset
= f
->stack_size
; /* FIXME: stack req. natural align */
395 stor
->size
= n_bytes
;
396 f
->stack_size
+= n_bytes
;
399 add_ptr_list(&f
->pseudo_list
, stor
);
404 static struct storage
*new_labelsym(struct symbol
*sym
)
406 struct storage
*stor
;
408 stor
= new_storage(STOR_LABELSYM
);
411 stor
->flags
|= STOR_WANTS_FREE
;
412 stor
->labelsym
= sym
;
418 static struct storage
*new_val(long long value
)
420 struct storage
*stor
;
422 stor
= new_storage(STOR_VALUE
);
425 stor
->flags
|= STOR_WANTS_FREE
;
432 static int new_label(void)
434 static int label
= 0;
438 static void textbuf_push(struct textbuf
**buf_p
, const char *text
)
440 struct textbuf
*tmp
, *list
= *buf_p
;
441 unsigned int text_len
= strlen(text
);
442 unsigned int alloc_len
= text_len
+ 1 + sizeof(*list
);
444 tmp
= calloc(1, alloc_len
);
446 die("OOM on textbuf alloc");
448 tmp
->text
= ((void *) tmp
) + sizeof(*tmp
);
449 memcpy(tmp
->text
, text
, text_len
+ 1);
452 /* add to end of list */
457 tmp
->prev
= list
->prev
;
458 tmp
->prev
->next
= tmp
;
466 static void textbuf_emit(struct textbuf
**buf_p
)
468 struct textbuf
*tmp
, *list
= *buf_p
;
472 if (tmp
->next
== tmp
)
475 tmp
->prev
->next
= tmp
->next
;
476 tmp
->next
->prev
= tmp
->prev
;
480 fputs(tmp
->text
, stdout
);
488 static void insn(const char *insn
, struct storage
*op1
, struct storage
*op2
,
489 const char *comment_in
)
491 struct function
*f
= current_func
;
492 struct atom
*atom
= new_atom(ATOM_INSN
);
494 assert(insn
!= NULL
);
496 strcpy(atom
->insn
, insn
);
497 if (comment_in
&& (*comment_in
))
498 strncpy(atom
->comment
, comment_in
,
499 sizeof(atom
->comment
) - 1);
507 static void emit_label (int label
, const char *comment
)
509 struct function
*f
= current_func
;
513 sprintf(s
, ".L%d:\n", label
);
515 sprintf(s
, ".L%d:\t\t\t\t\t# %s\n", label
, comment
);
517 push_text_atom(f
, s
);
520 static void emit_labelsym (struct symbol
*sym
, const char *comment
)
522 struct function
*f
= current_func
;
526 sprintf(s
, ".LS%p:\n", sym
);
528 sprintf(s
, ".LS%p:\t\t\t\t# %s\n", sym
, comment
);
530 push_text_atom(f
, s
);
533 static void emit_unit_pre(const char *basename
)
535 printf("\t.file\t\"%s\"\n", basename
);
538 static void emit_unit_post(void)
540 textbuf_emit(&unit_post_text
);
541 printf("\t.ident\t\"sparse silly x86 backend (built %s)\"\n", __DATE__
);
544 /* conditionally switch sections */
545 static void emit_section(const char *s
)
547 if (s
== current_section
)
549 if (current_section
&& (!strcmp(s
, current_section
)))
556 static void emit_insn_atom(struct function
*f
, struct atom
*atom
)
560 struct storage
*op1
= atom
->op1
;
561 struct storage
*op2
= atom
->op2
;
563 if (atom
->comment
[0])
564 sprintf(comment
, "\t\t# %s", atom
->comment
);
570 strcpy(tmp
, stor_op_name(op1
));
571 sprintf(s
, "\t%s\t%s, %s%s\n",
572 atom
->insn
, tmp
, stor_op_name(op2
), comment
);
573 } else if (atom
->op1
)
574 sprintf(s
, "\t%s\t%s%s%s\n",
575 atom
->insn
, stor_op_name(op1
),
576 comment
[0] ? "\t" : "", comment
);
578 sprintf(s
, "\t%s\t%s%s\n",
580 comment
[0] ? "\t\t" : "", comment
);
582 write(STDOUT_FILENO
, s
, strlen(s
));
585 static void emit_atom_list(struct function
*f
)
589 FOR_EACH_PTR(f
->atom_list
, atom
) {
590 switch (atom
->type
) {
592 ssize_t rc
= write(STDOUT_FILENO
, atom
->text
,
594 (void) rc
; /* FIXME */
598 emit_insn_atom(f
, atom
);
607 static void emit_string_list(struct function
*f
)
611 emit_section(".section\t.rodata");
613 FOR_EACH_PTR(f
->str_list
, atom
) {
614 /* FIXME: escape " in string */
615 printf(".L%d:\n", atom
->label
);
616 printf("\t.string\t%s\n", show_string(atom
->string
));
622 static void func_cleanup(struct function
*f
)
624 struct storage
*stor
;
627 FOR_EACH_PTR(f
->pseudo_list
, stor
) {
631 FOR_EACH_PTR(f
->atom_list
, atom
) {
632 if ((atom
->type
== ATOM_TEXT
) && (atom
->text
))
634 if (atom
->op1
&& (atom
->op1
->flags
& STOR_WANTS_FREE
))
636 if (atom
->op2
&& (atom
->op2
->flags
& STOR_WANTS_FREE
))
641 free_ptr_list(&f
->pseudo_list
);
645 /* function prologue */
646 static void emit_func_pre(struct symbol
*sym
)
650 unsigned int i
, argc
= 0, alloc_len
;
652 struct symbol_private
*privbase
;
653 struct storage
*storage_base
;
654 struct symbol
*base_type
= sym
->ctype
.base_type
;
656 FOR_EACH_PTR(base_type
->arguments
, arg
) {
662 (argc
* sizeof(struct symbol
*)) +
663 (argc
* sizeof(struct symbol_private
)) +
664 (argc
* sizeof(struct storage
));
665 mem
= calloc(1, alloc_len
);
667 die("OOM on func info");
669 f
= (struct function
*) mem
;
671 f
->argv
= (struct symbol
**) mem
;
672 mem
+= (argc
* sizeof(struct symbol
*));
673 privbase
= (struct symbol_private
*) mem
;
674 mem
+= (argc
* sizeof(struct symbol_private
));
675 storage_base
= (struct storage
*) mem
;
678 f
->ret_target
= new_label();
681 FOR_EACH_PTR(base_type
->arguments
, arg
) {
683 arg
->aux
= &privbase
[i
];
684 storage_base
[i
].type
= STOR_ARG
;
685 storage_base
[i
].idx
= i
;
686 privbase
[i
].addr
= &storage_base
[i
];
690 assert(current_func
== NULL
);
694 /* function epilogue */
695 static void emit_func_post(struct symbol
*sym
)
697 const char *name
= show_ident(sym
->ident
);
698 struct function
*f
= current_func
;
699 int stack_size
= f
->stack_size
;
704 /* function prologue */
705 emit_section(".text");
706 if ((sym
->ctype
.modifiers
& MOD_STATIC
) == 0)
707 printf(".globl %s\n", name
);
708 printf("\t.type\t%s, @function\n", name
);
709 printf("%s:\n", name
);
712 char pseudo_const
[16];
714 sprintf(pseudo_const
, "$%d", stack_size
);
715 printf("\tsubl\t%s, %%esp\n", pseudo_const
);
718 /* function epilogue */
720 /* jump target for 'return' statements */
721 emit_label(f
->ret_target
, NULL
);
726 val
= new_storage(STOR_VALUE
);
727 val
->value
= (long long) (stack_size
);
728 val
->flags
= STOR_WANTS_FREE
;
730 insn("addl", val
, REG_ESP
, NULL
);
733 insn("ret", NULL
, NULL
, NULL
);
735 /* output everything to stdout */
736 fflush(stdout
); /* paranoia; needed? */
739 /* function footer */
740 name
= show_ident(sym
->ident
);
741 printf("\t.size\t%s, .-%s\n", name
, name
);
747 /* emit object (a.k.a. variable, a.k.a. data) prologue */
748 static void emit_object_pre(const char *name
, unsigned long modifiers
,
749 unsigned long alignment
, unsigned int byte_size
)
751 if ((modifiers
& MOD_STATIC
) == 0)
752 printf(".globl %s\n", name
);
753 emit_section(".data");
755 printf("\t.align %lu\n", alignment
);
756 printf("\t.type\t%s, @object\n", name
);
757 printf("\t.size\t%s, %d\n", name
, byte_size
);
758 printf("%s:\n", name
);
761 /* emit value (only) for an initializer scalar */
762 static void emit_scalar(struct expression
*expr
, unsigned int bit_size
)
767 assert(expr
->type
== EXPR_VALUE
);
769 if (expr
->value
== 0ULL) {
770 printf("\t.zero\t%d\n", bit_size
/ 8);
774 ll
= (long long) expr
->value
;
777 case 8: type
= "byte"; ll
= (char) ll
; break;
778 case 16: type
= "value"; ll
= (short) ll
; break;
779 case 32: type
= "long"; ll
= (int) ll
; break;
780 case 64: type
= "quad"; break;
781 default: type
= NULL
; break;
784 assert(type
!= NULL
);
786 printf("\t.%s\t%Ld\n", type
, ll
);
789 static void emit_global_noinit(const char *name
, unsigned long modifiers
,
790 unsigned long alignment
, unsigned int byte_size
)
794 if (modifiers
& MOD_STATIC
) {
795 sprintf(s
, "\t.local\t%s\n", name
);
796 textbuf_push(&unit_post_text
, s
);
799 sprintf(s
, "\t.comm\t%s,%d,%lu\n", name
, byte_size
, alignment
);
801 sprintf(s
, "\t.comm\t%s,%d\n", name
, byte_size
);
802 textbuf_push(&unit_post_text
, s
);
805 static int ea_current
, ea_last
;
807 static void emit_initializer(struct symbol
*sym
,
808 struct expression
*expr
)
810 int distance
= ea_current
- ea_last
- 1;
813 printf("\t.zero\t%d\n", (sym
->bit_size
/ 8) * distance
);
815 if (expr
->type
== EXPR_VALUE
) {
816 struct symbol
*base_type
= sym
->ctype
.base_type
;
817 assert(base_type
!= NULL
);
819 emit_scalar(expr
, sym
->bit_size
/ get_expression_value(base_type
->array_size
));
822 if (expr
->type
!= EXPR_INITIALIZER
)
825 assert(0); /* FIXME */
828 static int sort_array_cmp(const struct expression
*a
,
829 const struct expression
*b
)
831 int a_ofs
= 0, b_ofs
= 0;
833 if (a
->type
== EXPR_POS
)
834 a_ofs
= (int) a
->init_offset
;
835 if (b
->type
== EXPR_POS
)
836 b_ofs
= (int) b
->init_offset
;
838 return a_ofs
- b_ofs
;
841 /* move to front-end? */
842 static void sort_array(struct expression
*expr
)
844 struct expression
*entry
, **list
;
845 unsigned int elem
, sorted
, i
;
848 FOR_EACH_PTR(expr
->expr_list
, entry
) {
855 list
= malloc(sizeof(entry
) * elem
);
857 die("OOM in sort_array");
859 /* this code is no doubt evil and ignores EXPR_INDEX possibly
860 * to its detriment and other nasty things. improvements
865 FOR_EACH_PTR(expr
->expr_list
, entry
) {
866 if ((entry
->type
== EXPR_POS
) || (entry
->type
== EXPR_VALUE
)) {
867 /* add entry to list[], in sorted order */
874 for (i
= 0; i
< sorted
; i
++)
875 if (sort_array_cmp(entry
, list
[i
]) <= 0)
878 /* If inserting into the middle of list[]
879 * instead of appending, we memmove.
880 * This is ugly, but thankfully
881 * uncommon. Input data with tons of
882 * entries very rarely have explicit
883 * offsets. convert to qsort eventually...
886 memmove(&list
[i
+ 1], &list
[i
],
887 (sorted
- i
) * sizeof(entry
));
895 FOR_EACH_PTR(expr
->expr_list
, entry
) {
896 if ((entry
->type
== EXPR_POS
) || (entry
->type
== EXPR_VALUE
))
897 __list
->list
[__i
] = list
[i
++];
902 static void emit_array(struct symbol
*sym
)
904 struct symbol
*base_type
= sym
->ctype
.base_type
;
905 struct expression
*expr
= sym
->initializer
;
906 struct expression
*entry
;
908 assert(base_type
!= NULL
);
914 emit_object_pre(show_ident(sym
->ident
), sym
->ctype
.modifiers
,
915 sym
->ctype
.alignment
,
920 FOR_EACH_PTR(expr
->expr_list
, entry
) {
921 if (entry
->type
== EXPR_VALUE
) {
923 emit_initializer(sym
, entry
);
924 ea_last
= ea_current
;
925 } else if (entry
->type
== EXPR_POS
) {
927 entry
->init_offset
/ (base_type
->bit_size
/ 8);
928 emit_initializer(sym
, entry
->init_expr
);
929 ea_last
= ea_current
;
934 static void emit_one_symbol(struct symbol
*sym
, void *dummy
, int flags
)
939 void emit_unit(const char *basename
, struct symbol_list
*list
)
941 emit_unit_pre(basename
);
942 symbol_iterate(list
, emit_one_symbol
, NULL
);
946 static void emit_copy(struct storage
*dest
, struct storage
*src
,
947 struct symbol
*ctype
)
949 struct storage
*reg
= NULL
;
950 unsigned int bit_size
;
952 /* FIXME: Bitfield copy! */
954 bit_size
= src
->size
* 8;
957 if ((src
->type
== STOR_ARG
) && (bit_size
< 32))
960 reg
= temp_from_bits(bit_size
);
961 emit_move(src
, reg
, ctype
, "begin copy ..");
963 bit_size
= dest
->size
* 8;
966 if ((dest
->type
== STOR_ARG
) && (bit_size
< 32))
969 reg
= temp_from_bits(bit_size
);
970 emit_move(reg
, dest
, ctype
, ".... end copy");
973 static void emit_store(struct expression
*dest_expr
, struct storage
*dest
,
974 struct storage
*src
, int bits
)
976 /* FIXME: Bitfield store! */
977 printf("\tst.%d\t\tv%d,[v%d]\n", bits
, src
->pseudo
, dest
->pseudo
);
980 static void emit_scalar_noinit(struct symbol
*sym
)
982 emit_global_noinit(show_ident(sym
->ident
),
983 sym
->ctype
.modifiers
, sym
->ctype
.alignment
,
988 static void emit_array_noinit(struct symbol
*sym
)
990 emit_global_noinit(show_ident(sym
->ident
),
991 sym
->ctype
.modifiers
, sym
->ctype
.alignment
,
992 get_expression_value(sym
->array_size
) * (sym
->bit_size
/ 8));
996 static const char *opbits(const char *insn
, unsigned int bits
)
998 static char opbits_str
[32];
1002 case 8: c
= 'b'; break;
1003 case 16: c
= 'w'; break;
1004 case 32: c
= 'l'; break;
1005 case 64: c
= 'q'; break;
1006 default: assert(0); break;
1009 sprintf(opbits_str
, "%s%c", insn
, c
);
1014 static void emit_move(struct storage
*src
, struct storage
*dest
,
1015 struct symbol
*ctype
, const char *comment
)
1018 unsigned int is_signed
;
1019 unsigned int is_dest
= (src
->type
== STOR_REG
);
1023 bits
= ctype
->bit_size
;
1024 is_signed
= type_is_signed(ctype
);
1030 if ((dest
->type
== STOR_REG
) && (src
->type
== STOR_REG
)) {
1031 insn("mov", src
, dest
, NULL
);
1035 if ((bits
== 8) || (bits
== 16)) {
1039 opname
= is_signed
? "movsx" : "movzx";
1043 insn(opbits(opname
, bits
), src
, dest
, comment
);
1046 static struct storage
*emit_compare(struct expression
*expr
)
1048 struct storage
*left
= x86_expression(expr
->left
);
1049 struct storage
*right
= x86_expression(expr
->right
);
1050 struct storage
*new, *val
;
1051 const char *opname
= NULL
;
1052 unsigned int right_bits
= expr
->right
->ctype
->bit_size
;
1055 case '<': opname
= "setl"; break;
1056 case '>': opname
= "setg"; break;
1058 opname
= "setle"; break;
1060 opname
= "setge"; break;
1061 case SPECIAL_EQUAL
: opname
= "sete"; break;
1062 case SPECIAL_NOTEQUAL
: opname
= "setne"; break;
1063 case SPECIAL_UNSIGNED_LT
:
1064 opname
= "setb"; break;
1065 case SPECIAL_UNSIGNED_GT
:
1066 opname
= "seta"; break;
1067 case SPECIAL_UNSIGNED_LTE
:
1068 opname
= "setb"; break;
1069 case SPECIAL_UNSIGNED_GTE
:
1070 opname
= "setae"; break;
1077 val
= new_storage(STOR_VALUE
);
1078 val
->flags
= STOR_WANTS_FREE
;
1079 emit_move(val
, REG_EDX
, NULL
, NULL
);
1081 /* move op1 into EAX */
1082 emit_move(left
, REG_EAX
, expr
->left
->ctype
, NULL
);
1084 /* perform comparison, RHS (op1, right) and LHS (op2, EAX) */
1085 insn(opbits("cmp", right_bits
), right
, REG_EAX
, NULL
);
1087 /* store result of operation, 0 or 1, in DL using SETcc */
1088 insn(opname
, REG_DL
, NULL
, NULL
);
1090 /* finally, store the result (DL) in a new pseudo / stack slot */
1091 new = stack_alloc(4);
1092 emit_move(REG_EDX
, new, NULL
, "end EXPR_COMPARE");
1097 static struct storage
*emit_value(struct expression
*expr
)
1099 #if 0 /* old and slow way */
1100 struct storage
*new = stack_alloc(4);
1101 struct storage
*val
;
1103 val
= new_storage(STOR_VALUE
);
1104 val
->value
= (long long) expr
->value
;
1105 val
->flags
= STOR_WANTS_FREE
;
1106 insn("movl", val
, new, NULL
);
1110 struct storage
*val
;
1112 val
= new_storage(STOR_VALUE
);
1113 val
->value
= (long long) expr
->value
;
1115 return val
; /* FIXME: memory leak */
1119 static struct storage
*emit_binop(struct expression
*expr
)
1121 struct storage
*left
= x86_expression(expr
->left
);
1122 struct storage
*right
= x86_expression(expr
->right
);
1123 struct storage
*new;
1124 struct storage
*accum_reg
= NULL
;
1125 struct storage
*result_reg
= NULL
;
1126 const char *opname
= NULL
;
1128 char movstr
[16], opstr
[16];
1129 int is_signed
, doing_divide
= 0;
1131 if ((expr
->op
== '/') || (expr
->op
== '%')) {
1132 struct storage
*val
;
1136 val
= new_storage(STOR_VALUE
);
1137 val
->flags
= STOR_WANTS_FREE
;
1138 emit_move(val
, REG_EDX
, NULL
, "begin EXPR_DIVIDE");
1141 is_signed
= type_is_signed(expr
->ctype
);
1159 case SPECIAL_LEFTSHIFT
:
1162 case SPECIAL_RIGHTSHIFT
:
1181 case SPECIAL_LOGICAL_AND
:
1182 warn(expr
->pos
, "bogus bitwise and for logical op (should use '2*setne + and' or something)");
1185 case SPECIAL_LOGICAL_OR
:
1186 warn(expr
->pos
, "bogus bitwise or for logical op (should use 'or + setne' or something)");
1190 error(expr
->pos
, "unhandled binop '%s'\n", show_special(expr
->op
));
1194 switch (expr
->ctype
->bit_size
) {
1197 result_reg
= accum_reg
= REG_AL
;
1198 if (expr
->op
== '%')
1199 result_reg
= REG_DL
;
1203 result_reg
= accum_reg
= REG_AX
;
1204 if (expr
->op
== '%')
1205 result_reg
= REG_DX
;
1209 result_reg
= accum_reg
= REG_EAX
;
1210 if (expr
->op
== '%')
1211 result_reg
= REG_EDX
;
1214 suffix
= "q"; /* FIXME */
1215 result_reg
= accum_reg
= REG_EAX
; /* FIXME */
1216 if (expr
->op
== '%')
1217 result_reg
= REG_EDX
;
1224 sprintf(movstr
, "mov%s", suffix
);
1225 sprintf(opstr
, "%s%s", opname
, suffix
);
1227 /* load op2 into EAX */
1228 insn(movstr
, right
, accum_reg
,
1229 doing_divide
? NULL
: "EXPR_BINOP/COMMA/LOGICAL");
1232 insn(opstr
, left
, accum_reg
, NULL
);
1234 /* store result (EAX or EDX) in new pseudo / stack slot */
1235 new = stack_alloc(expr
->ctype
->bit_size
/ 8);
1236 insn(movstr
, result_reg
, new,
1237 doing_divide
? "end EXPR_DIVIDE" : "end EXPR_BINOP");
1242 static int emit_conditional_test(struct storage
*val
)
1244 struct storage
*target_val
;
1247 /* load result into EAX */
1248 insn("movl", val
, REG_EAX
, "begin if/conditional");
1250 /* compare result with zero */
1251 insn("test", REG_EAX
, REG_EAX
, NULL
);
1253 /* create conditional-failed label to jump to */
1254 target_false
= new_label();
1255 target_val
= new_storage(STOR_LABEL
);
1256 target_val
->label
= target_false
;
1257 target_val
->flags
= STOR_WANTS_FREE
;
1258 insn("jz", target_val
, NULL
, NULL
);
1260 return target_false
;
1263 static int emit_conditional_end(int target_false
)
1265 struct storage
*cond_end_st
;
1268 /* finished generating code for if-true statement.
1269 * add a jump-to-end jump to avoid falling through
1270 * to the if-false statement code.
1272 cond_end
= new_label();
1273 cond_end_st
= new_storage(STOR_LABEL
);
1274 cond_end_st
->label
= cond_end
;
1275 cond_end_st
->flags
= STOR_WANTS_FREE
;
1276 insn("jmp", cond_end_st
, NULL
, NULL
);
1278 /* if we have both if-true and if-false statements,
1279 * the failed-conditional case will fall through to here
1281 emit_label(target_false
, NULL
);
1286 static void emit_if_conditional(struct statement
*stmt
)
1288 struct storage
*val
;
1291 /* emit test portion of conditional */
1292 val
= x86_expression(stmt
->if_conditional
);
1293 cond_end
= emit_conditional_test(val
);
1295 /* emit if-true statement */
1296 x86_statement(stmt
->if_true
);
1298 /* emit if-false statement, if present */
1299 if (stmt
->if_false
) {
1300 cond_end
= emit_conditional_end(cond_end
);
1301 x86_statement(stmt
->if_false
);
1304 /* end of conditional; jump target for if-true branch */
1305 emit_label(cond_end
, "end if");
1308 static struct storage
*emit_inc_dec(struct expression
*expr
, int postop
)
1310 struct storage
*addr
= x86_address_gen(expr
->unop
);
1311 struct storage
*retval
;
1314 strcpy(opname
, opbits(expr
->op
== SPECIAL_INCREMENT
? "inc" : "dec",
1315 expr
->ctype
->bit_size
));
1318 struct storage
*new = stack_alloc(4);
1320 emit_copy(new, addr
, expr
->unop
->ctype
);
1326 insn(opname
, addr
, NULL
, NULL
);
1331 static struct storage
*emit_postop(struct expression
*expr
)
1333 return emit_inc_dec(expr
, 1);
1336 static struct storage
*emit_return_stmt(struct statement
*stmt
)
1338 struct function
*f
= current_func
;
1339 struct expression
*expr
= stmt
->ret_value
;
1340 struct storage
*val
= NULL
, *jmplbl
;
1342 if (expr
&& expr
->ctype
) {
1343 val
= x86_expression(expr
);
1344 assert(val
!= NULL
);
1345 emit_move(val
, REG_EAX
, expr
->ctype
, "return");
1348 jmplbl
= new_storage(STOR_LABEL
);
1349 jmplbl
->flags
|= STOR_WANTS_FREE
;
1350 jmplbl
->label
= f
->ret_target
;
1351 insn("jmp", jmplbl
, NULL
, NULL
);
1356 static struct storage
*emit_conditional_expr(struct expression
*expr
)
1358 struct storage
*cond
, *true = NULL
, *false = NULL
;
1359 struct storage
*new = stack_alloc(expr
->ctype
->bit_size
/ 8);
1360 int target_false
, cond_end
;
1362 /* evaluate conditional */
1363 cond
= x86_expression(expr
->conditional
);
1364 target_false
= emit_conditional_test(cond
);
1366 /* handle if-true part of the expression */
1367 if (!expr
->cond_true
)
1370 true = x86_expression(expr
->cond_true
);
1372 emit_copy(new, true, expr
->ctype
);
1374 cond_end
= emit_conditional_end(target_false
);
1376 /* handle if-false part of the expression */
1377 false = x86_expression(expr
->cond_false
);
1379 emit_copy(new, false, expr
->ctype
);
1381 /* end of conditional; jump target for if-true branch */
1382 emit_label(cond_end
, "end conditional");
1387 static struct storage
*emit_select_expr(struct expression
*expr
)
1389 struct storage
*cond
= x86_expression(expr
->conditional
);
1390 struct storage
*true = x86_expression(expr
->cond_true
);
1391 struct storage
*false = x86_expression(expr
->cond_false
);
1392 struct storage
*new = stack_alloc(4);
1393 struct storage
*truereg
;
1395 emit_move(cond
, REG_EAX
, expr
->conditional
->ctype
, "begin SELECT");
1398 emit_move(true, REG_ECX
, expr
->cond_true
->ctype
, NULL
);
1401 emit_move(false, REG_EDX
, expr
->cond_false
->ctype
, NULL
);
1404 * Do the actual select: check the conditional for zero,
1405 * move false over true if zero
1407 insn("test", REG_EAX
, REG_EAX
, NULL
);
1408 insn("cmovz", REG_EDX
, truereg
, NULL
);
1411 emit_move(truereg
, new, expr
->ctype
, "end SELECT");
1415 static struct storage
*emit_symbol_expr_init(struct symbol
*sym
)
1417 struct expression
*expr
= sym
->initializer
;
1418 struct symbol_private
*priv
= sym
->aux
;
1421 priv
= calloc(1, sizeof(*priv
));
1425 struct storage
*new = stack_alloc(4);
1426 fprintf(stderr
, "FIXME! no value for symbol %s. creating pseudo %d (stack offset %d)\n",
1427 show_ident(sym
->ident
),
1428 new->pseudo
, new->pseudo
* 4);
1431 priv
->addr
= x86_expression(expr
);
1438 static struct storage
*emit_string_expr(struct expression
*expr
)
1440 struct function
*f
= current_func
;
1441 int label
= new_label();
1442 struct storage
*new;
1444 push_cstring(f
, expr
->string
, label
);
1446 new = new_storage(STOR_LABEL
);
1448 new->flags
= STOR_LABEL_VAL
| STOR_WANTS_FREE
;
1452 static struct storage
*emit_cast_expr(struct expression
*expr
)
1454 struct symbol
*old_type
, *new_type
;
1455 struct storage
*op
= x86_expression(expr
->cast_expression
);
1456 int oldbits
, newbits
;
1457 struct storage
*new;
1459 old_type
= expr
->cast_expression
->ctype
;
1460 new_type
= expr
->cast_type
;
1462 oldbits
= old_type
->bit_size
;
1463 newbits
= new_type
->bit_size
;
1464 if (oldbits
>= newbits
)
1467 emit_move(op
, REG_EAX
, old_type
, "begin cast ..");
1469 new = stack_alloc(newbits
/ 8);
1470 emit_move(REG_EAX
, new, new_type
, ".... end cast");
1475 static struct storage
*emit_regular_preop(struct expression
*expr
)
1477 struct storage
*target
= x86_expression(expr
->unop
);
1478 struct storage
*val
, *new = stack_alloc(4);
1479 const char *opname
= NULL
;
1483 val
= new_storage(STOR_VALUE
);
1484 val
->flags
= STOR_WANTS_FREE
;
1485 emit_move(val
, REG_EDX
, NULL
, NULL
);
1486 emit_move(target
, REG_EAX
, expr
->unop
->ctype
, NULL
);
1487 insn("test", REG_EAX
, REG_EAX
, NULL
);
1488 insn("setz", REG_DL
, NULL
, NULL
);
1489 emit_move(REG_EDX
, new, expr
->unop
->ctype
, NULL
);
1497 emit_move(target
, REG_EAX
, expr
->unop
->ctype
, NULL
);
1498 insn(opname
, REG_EAX
, NULL
, NULL
);
1499 emit_move(REG_EAX
, new, expr
->unop
->ctype
, NULL
);
1509 static void emit_case_statement(struct statement
*stmt
)
1511 emit_labelsym(stmt
->case_label
, NULL
);
1512 x86_statement(stmt
->case_statement
);
1515 static void emit_switch_statement(struct statement
*stmt
)
1517 struct storage
*val
= x86_expression(stmt
->switch_expression
);
1518 struct symbol
*sym
, *default_sym
= NULL
;
1519 struct storage
*labelsym
, *label
;
1522 emit_move(val
, REG_EAX
, stmt
->switch_expression
->ctype
, "begin case");
1525 * This is where a _real_ back-end would go through the
1526 * cases to decide whether to use a lookup table or a
1527 * series of comparisons etc
1529 FOR_EACH_PTR(stmt
->switch_case
->symbol_list
, sym
) {
1530 struct statement
*case_stmt
= sym
->stmt
;
1531 struct expression
*expr
= case_stmt
->case_expression
;
1532 struct expression
*to
= case_stmt
->case_to
;
1540 struct storage
*case_val
= new_val(expr
->value
);
1542 assert (expr
->type
== EXPR_VALUE
);
1544 insn("cmpl", case_val
, REG_EAX
, NULL
);
1547 labelsym
= new_labelsym(sym
);
1548 insn("je", labelsym
, NULL
, NULL
);
1552 label
= new_storage(STOR_LABEL
);
1553 label
->flags
|= STOR_WANTS_FREE
;
1554 label
->label
= next_test
= new_label();
1556 /* FIXME: signed/unsigned */
1557 insn("jl", label
, NULL
, NULL
);
1559 case_val
= new_val(to
->value
);
1560 insn("cmpl", case_val
, REG_EAX
, NULL
);
1562 /* TODO: implement and use refcounting... */
1563 label
= new_storage(STOR_LABEL
);
1564 label
->flags
|= STOR_WANTS_FREE
;
1565 label
->label
= next_test
;
1567 /* FIXME: signed/unsigned */
1568 insn("jg", label
, NULL
, NULL
);
1570 labelsym
= new_labelsym(sym
);
1571 insn("jmp", labelsym
, NULL
, NULL
);
1573 emit_label(next_test
, NULL
);
1579 labelsym
= new_labelsym(default_sym
);
1580 insn("jmp", labelsym
, NULL
, "default");
1582 label
= new_storage(STOR_LABEL
);
1583 label
->flags
|= STOR_WANTS_FREE
;
1584 label
->label
= switch_end
= new_label();
1585 insn("jmp", label
, NULL
, "goto end of switch");
1588 x86_statement(stmt
->switch_statement
);
1590 if (stmt
->switch_break
->used
)
1591 emit_labelsym(stmt
->switch_break
, NULL
);
1594 emit_label(switch_end
, NULL
);
1597 static void x86_struct_member(struct symbol
*sym
, void *data
, int flags
)
1599 if (flags
& ITERATE_FIRST
)
1601 printf("%s:%d:%ld at offset %ld", show_ident(sym
->ident
), sym
->bit_size
, sym
->ctype
.alignment
, sym
->offset
);
1602 if (sym
->fieldwidth
)
1603 printf("[%d..%d]", sym
->bit_offset
, sym
->bit_offset
+sym
->fieldwidth
-1);
1604 if (flags
& ITERATE_LAST
)
1610 static void x86_symbol(struct symbol
*sym
)
1612 struct symbol
*type
;
1617 type
= sym
->ctype
.base_type
;
1622 * Show actual implementation information
1624 switch (type
->type
) {
1627 if (sym
->initializer
)
1630 emit_array_noinit(sym
);
1634 if (sym
->initializer
) {
1635 emit_object_pre(show_ident(sym
->ident
),
1636 sym
->ctype
.modifiers
,
1637 sym
->ctype
.alignment
,
1639 emit_scalar(sym
->initializer
, sym
->bit_size
);
1642 emit_scalar_noinit(sym
);
1646 symbol_iterate(type
->symbol_list
, x86_struct_member
, NULL
);
1650 symbol_iterate(type
->symbol_list
, x86_struct_member
, NULL
);
1654 struct statement
*stmt
= type
->stmt
;
1657 x86_statement(stmt
);
1658 emit_func_post(sym
);
1667 if (sym
->initializer
&& (type
->type
!= SYM_BASETYPE
) &&
1668 (type
->type
!= SYM_ARRAY
)) {
1670 x86_expression(sym
->initializer
);
1674 static void x86_symbol_init(struct symbol
*sym
);
1676 static void x86_symbol_decl(struct symbol_list
*syms
)
1679 FOR_EACH_PTR(syms
, sym
) {
1680 x86_symbol_init(sym
);
1684 static void loopstk_push(int cont_lbl
, int loop_bottom_lbl
)
1686 struct function
*f
= current_func
;
1687 struct loop_stack
*ls
;
1689 ls
= malloc(sizeof(*ls
));
1690 ls
->continue_lbl
= cont_lbl
;
1691 ls
->loop_bottom_lbl
= loop_bottom_lbl
;
1692 ls
->next
= f
->loop_stack
;
1696 static void loopstk_pop(void)
1698 struct function
*f
= current_func
;
1699 struct loop_stack
*ls
;
1701 assert(f
->loop_stack
!= NULL
);
1703 f
->loop_stack
= f
->loop_stack
->next
;
1707 static int loopstk_break(void)
1709 return current_func
->loop_stack
->loop_bottom_lbl
;
1712 static int loopstk_continue(void)
1714 return current_func
->loop_stack
->continue_lbl
;
1717 static void emit_loop(struct statement
*stmt
)
1719 struct statement
*pre_statement
= stmt
->iterator_pre_statement
;
1720 struct expression
*pre_condition
= stmt
->iterator_pre_condition
;
1721 struct statement
*statement
= stmt
->iterator_statement
;
1722 struct statement
*post_statement
= stmt
->iterator_post_statement
;
1723 struct expression
*post_condition
= stmt
->iterator_post_condition
;
1724 int loop_top
= 0, loop_bottom
, loop_continue
;
1725 int have_bottom
= 0;
1726 struct storage
*val
;
1728 loop_bottom
= new_label();
1729 loop_continue
= new_label();
1730 loopstk_push(loop_continue
, loop_bottom
);
1732 x86_symbol_decl(stmt
->iterator_syms
);
1733 x86_statement(pre_statement
);
1734 if (pre_condition
) {
1735 if (pre_condition
->type
== EXPR_VALUE
) {
1736 if (!pre_condition
->value
) {
1737 struct storage
*lbv
;
1738 lbv
= new_storage(STOR_LABEL
);
1739 lbv
->label
= loop_bottom
;
1740 lbv
->flags
= STOR_WANTS_FREE
;
1741 insn("jmp", lbv
, NULL
, "go to loop bottom");
1745 struct storage
*lbv
= new_storage(STOR_LABEL
);
1746 lbv
->label
= loop_bottom
;
1747 lbv
->flags
= STOR_WANTS_FREE
;
1750 val
= x86_expression(pre_condition
);
1752 emit_move(val
, REG_EAX
, NULL
, "loop pre condition");
1753 insn("test", REG_EAX
, REG_EAX
, NULL
);
1754 insn("jz", lbv
, NULL
, NULL
);
1757 if (!post_condition
|| post_condition
->type
!= EXPR_VALUE
|| post_condition
->value
) {
1758 loop_top
= new_label();
1759 emit_label(loop_top
, "loop top");
1761 x86_statement(statement
);
1762 if (stmt
->iterator_continue
->used
)
1763 emit_label(loop_continue
, "'continue' iterator");
1764 x86_statement(post_statement
);
1765 if (!post_condition
) {
1766 struct storage
*lbv
= new_storage(STOR_LABEL
);
1767 lbv
->label
= loop_top
;
1768 lbv
->flags
= STOR_WANTS_FREE
;
1769 insn("jmp", lbv
, NULL
, "go to loop top");
1770 } else if (post_condition
->type
== EXPR_VALUE
) {
1771 if (post_condition
->value
) {
1772 struct storage
*lbv
= new_storage(STOR_LABEL
);
1773 lbv
->label
= loop_top
;
1774 lbv
->flags
= STOR_WANTS_FREE
;
1775 insn("jmp", lbv
, NULL
, "go to loop top");
1778 struct storage
*lbv
= new_storage(STOR_LABEL
);
1779 lbv
->label
= loop_top
;
1780 lbv
->flags
= STOR_WANTS_FREE
;
1782 val
= x86_expression(post_condition
);
1784 emit_move(val
, REG_EAX
, NULL
, "loop post condition");
1785 insn("test", REG_EAX
, REG_EAX
, NULL
);
1786 insn("jnz", lbv
, NULL
, NULL
);
1788 if (have_bottom
|| stmt
->iterator_break
->used
)
1789 emit_label(loop_bottom
, "loop bottom");
1795 * Print out a statement
1797 static struct storage
*x86_statement(struct statement
*stmt
)
1801 switch (stmt
->type
) {
1803 return emit_return_stmt(stmt
);
1804 case STMT_COMPOUND
: {
1805 struct statement
*s
;
1806 struct storage
*last
= NULL
;
1808 x86_symbol_decl(stmt
->syms
);
1809 FOR_EACH_PTR(stmt
->stmts
, s
) {
1810 last
= x86_statement(s
);
1816 case STMT_EXPRESSION
:
1817 return x86_expression(stmt
->expression
);
1819 emit_if_conditional(stmt
);
1823 emit_case_statement(stmt
);
1826 emit_switch_statement(stmt
);
1837 printf(".L%p:\n", stmt
->label_identifier
);
1838 x86_statement(stmt
->label_statement
);
1842 if (stmt
->goto_expression
) {
1843 struct storage
*val
= x86_expression(stmt
->goto_expression
);
1844 printf("\tgoto *v%d\n", val
->pseudo
);
1845 } else if (!strcmp("break", show_ident(stmt
->goto_label
->ident
))) {
1846 struct storage
*lbv
= new_storage(STOR_LABEL
);
1847 lbv
->label
= loopstk_break();
1848 lbv
->flags
= STOR_WANTS_FREE
;
1849 insn("jmp", lbv
, NULL
, "'break'; go to loop bottom");
1850 } else if (!strcmp("continue", show_ident(stmt
->goto_label
->ident
))) {
1851 struct storage
*lbv
= new_storage(STOR_LABEL
);
1852 lbv
->label
= loopstk_continue();
1853 lbv
->flags
= STOR_WANTS_FREE
;
1854 insn("jmp", lbv
, NULL
, "'continue'; go to loop top");
1856 struct storage
*labelsym
= new_labelsym(stmt
->goto_label
);
1857 insn("jmp", labelsym
, NULL
, NULL
);
1861 printf("\tasm( .... )\n");
1867 static struct storage
*x86_call_expression(struct expression
*expr
)
1869 struct function
*f
= current_func
;
1870 struct symbol
*direct
;
1871 struct expression
*arg
, *fn
;
1872 struct storage
*retval
, *fncall
;
1877 warn(expr
->pos
, "\tcall with no type!");
1882 FOR_EACH_PTR_REVERSE(expr
->args
, arg
) {
1883 struct storage
*new = x86_expression(arg
);
1884 int size
= arg
->ctype
->bit_size
;
1887 * FIXME: i386 SysV ABI dictates that values
1888 * smaller than 32 bits should be placed onto
1889 * the stack as 32-bit objects. We should not
1890 * blindly do a 32-bit push on objects smaller
1895 insn("pushl", new, NULL
,
1896 !framesize
? "begin function call" : NULL
);
1898 framesize
+= size
>> 3;
1899 } END_FOR_EACH_PTR_REVERSE
;
1903 /* Remove dereference, if any */
1905 if (fn
->type
== EXPR_PREOP
) {
1906 if (fn
->unop
->type
== EXPR_SYMBOL
) {
1907 struct symbol
*sym
= fn
->unop
->symbol
;
1908 if (sym
->ctype
.base_type
->type
== SYM_FN
)
1913 struct storage
*direct_stor
= new_storage(STOR_SYM
);
1914 direct_stor
->flags
|= STOR_WANTS_FREE
;
1915 direct_stor
->sym
= direct
;
1916 insn("call", direct_stor
, NULL
, NULL
);
1918 fncall
= x86_expression(fn
);
1919 emit_move(fncall
, REG_EAX
, fn
->ctype
, NULL
);
1921 strcpy(s
, "\tcall\t*%eax\n");
1922 push_text_atom(f
, s
);
1925 /* FIXME: pay attention to BITS_IN_POINTER */
1927 struct storage
*val
= new_storage(STOR_VALUE
);
1928 val
->value
= (long long) framesize
;
1929 val
->flags
= STOR_WANTS_FREE
;
1930 insn("addl", val
, REG_ESP
, NULL
);
1933 retval
= stack_alloc(4);
1934 emit_move(REG_EAX
, retval
, NULL
, "end function call");
1939 static struct storage
*x86_address_gen(struct expression
*expr
)
1941 struct function
*f
= current_func
;
1942 struct storage
*addr
;
1943 struct storage
*new;
1946 if ((expr
->type
!= EXPR_PREOP
) || (expr
->op
!= '*'))
1947 return x86_expression(expr
->address
);
1949 addr
= x86_expression(expr
->unop
);
1950 if (expr
->unop
->type
== EXPR_SYMBOL
)
1953 emit_move(addr
, REG_EAX
, NULL
, "begin deref ..");
1955 /* FIXME: operand size */
1956 strcpy(s
, "\tmovl\t(%eax), %ecx\n");
1957 push_text_atom(f
, s
);
1959 new = stack_alloc(4);
1960 emit_move(REG_ECX
, new, NULL
, ".... end deref");
1965 static struct storage
*x86_assignment(struct expression
*expr
)
1967 struct expression
*target
= expr
->left
;
1968 struct storage
*val
, *addr
;
1973 val
= x86_expression(expr
->right
);
1974 addr
= x86_address_gen(target
);
1976 switch (val
->type
) {
1977 /* copy, where both operands are memory */
1980 emit_copy(addr
, val
, expr
->ctype
);
1983 /* copy, one or zero operands are memory */
1988 emit_move(val
, addr
, expr
->left
->ctype
, NULL
);
1998 static int x86_initialization(struct symbol
*sym
, struct expression
*expr
)
2000 struct storage
*val
, *addr
;
2006 bits
= expr
->ctype
->bit_size
;
2007 val
= x86_expression(expr
);
2008 addr
= x86_symbol_expr(sym
);
2009 // FIXME! The "target" expression is for bitfield store information.
2010 // Leave it NULL, which works fine.
2011 emit_store(NULL
, addr
, val
, bits
);
2015 static struct storage
*x86_access(struct expression
*expr
)
2017 return x86_address_gen(expr
);
2020 static struct storage
*x86_preop(struct expression
*expr
)
2023 * '*' is an lvalue access, and is fundamentally different
2024 * from an arithmetic operation. Maybe it should have an
2025 * expression type of its own..
2027 if (expr
->op
== '*')
2028 return x86_access(expr
);
2029 if (expr
->op
== SPECIAL_INCREMENT
|| expr
->op
== SPECIAL_DECREMENT
)
2030 return emit_inc_dec(expr
, 0);
2031 return emit_regular_preop(expr
);
2034 static struct storage
*x86_symbol_expr(struct symbol
*sym
)
2036 struct storage
*new = stack_alloc(4);
2038 if (sym
->ctype
.modifiers
& (MOD_TOPLEVEL
| MOD_EXTERN
| MOD_STATIC
)) {
2039 printf("\tmovi.%d\t\tv%d,$%s\n", bits_in_pointer
, new->pseudo
, show_ident(sym
->ident
));
2042 if (sym
->ctype
.modifiers
& MOD_ADDRESSABLE
) {
2043 printf("\taddi.%d\t\tv%d,vFP,$%lld\n", bits_in_pointer
, new->pseudo
, sym
->value
);
2046 printf("\taddi.%d\t\tv%d,vFP,$offsetof(%s:%p)\n", bits_in_pointer
, new->pseudo
, show_ident(sym
->ident
), sym
);
2050 static void x86_symbol_init(struct symbol
*sym
)
2052 struct symbol_private
*priv
= sym
->aux
;
2053 struct expression
*expr
= sym
->initializer
;
2054 struct storage
*new;
2057 new = x86_expression(expr
);
2059 new = stack_alloc(sym
->bit_size
/ 8);
2062 priv
= calloc(1, sizeof(*priv
));
2064 /* FIXME: leak! we don't free... */
2065 /* (well, we don't free symbols either) */
2071 static int type_is_signed(struct symbol
*sym
)
2073 if (sym
->type
== SYM_NODE
)
2074 sym
= sym
->ctype
.base_type
;
2075 if (sym
->type
== SYM_PTR
)
2077 return !(sym
->ctype
.modifiers
& MOD_UNSIGNED
);
2080 static struct storage
*x86_bitfield_expr(struct expression
*expr
)
2082 return x86_access(expr
);
2085 static struct storage
*x86_label_expr(struct expression
*expr
)
2087 struct storage
*new = stack_alloc(4);
2088 printf("\tmovi.%d\t\tv%d,.L%p\n", bits_in_pointer
, new->pseudo
, expr
->label_symbol
);
2092 static struct storage
*x86_statement_expr(struct expression
*expr
)
2094 return x86_statement(expr
->statement
);
2097 static int x86_position_expr(struct expression
*expr
, struct symbol
*base
)
2099 struct storage
*new = x86_expression(expr
->init_expr
);
2100 struct symbol
*ctype
= expr
->init_sym
;
2102 printf("\tinsert v%d at [%d:%d] of %s\n", new->pseudo
,
2103 expr
->init_offset
, ctype
->bit_offset
,
2104 show_ident(base
->ident
));
2108 static void x86_initializer_expr(struct expression
*expr
, struct symbol
*ctype
)
2110 struct expression
*entry
;
2112 FOR_EACH_PTR(expr
->expr_list
, entry
) {
2113 // Nested initializers have their positions already
2114 // recursively calculated - just output them too
2115 if (entry
->type
== EXPR_INITIALIZER
) {
2116 x86_initializer_expr(entry
, ctype
);
2120 // Ignore initializer indexes and identifiers - the
2121 // evaluator has taken them into account
2122 if (entry
->type
== EXPR_IDENTIFIER
|| entry
->type
== EXPR_INDEX
)
2124 if (entry
->type
== EXPR_POS
) {
2125 x86_position_expr(entry
, ctype
);
2128 x86_initialization(ctype
, entry
);
2133 * Print out an expression. Return the pseudo that contains the
2136 static struct storage
*x86_expression(struct expression
*expr
)
2142 struct position
*pos
= &expr
->pos
;
2143 printf("\tno type at %s:%d:%d\n",
2144 input_streams
[pos
->stream
].name
,
2145 pos
->line
, pos
->pos
);
2149 switch (expr
->type
) {
2151 return x86_call_expression(expr
);
2153 case EXPR_ASSIGNMENT
:
2154 return x86_assignment(expr
);
2157 return emit_compare(expr
);
2161 return emit_binop(expr
);
2163 return x86_preop(expr
);
2165 return emit_postop(expr
);
2167 return emit_symbol_expr_init(expr
->symbol
);
2171 warn(expr
->pos
, "invalid expression after evaluation");
2174 return emit_cast_expr(expr
);
2176 return emit_value(expr
);
2178 return emit_string_expr(expr
);
2180 return x86_bitfield_expr(expr
);
2181 case EXPR_INITIALIZER
:
2182 x86_initializer_expr(expr
, expr
->ctype
);
2185 return emit_select_expr(expr
);
2186 case EXPR_CONDITIONAL
:
2187 return emit_conditional_expr(expr
);
2188 case EXPR_STATEMENT
:
2189 return x86_statement_expr(expr
);
2191 return x86_label_expr(expr
);
2193 // None of these should exist as direct expressions: they are only
2194 // valid as sub-expressions of initializers.
2196 warn(expr
->pos
, "unable to show plain initializer position expression");
2198 case EXPR_IDENTIFIER
:
2199 warn(expr
->pos
, "unable to show identifier expression");
2202 warn(expr
->pos
, "unable to show index expression");
2205 warn(expr
->pos
, "unable to show type expression");
2208 warn(expr
->pos
, "floating point support is not implemented");