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"
45 unsigned int len
; /* does NOT include terminating null */
54 struct loop_stack
*next
;
60 struct ptr_list
*pseudo_list
;
61 struct ptr_list
*atom_list
;
62 struct ptr_list
*str_list
;
63 struct loop_stack
*loop_stack
;
70 STOR_PSEUDO
, /* variable stored on the stack */
71 STOR_ARG
, /* function argument */
72 STOR_SYM
, /* a symbol we can directly ref in the asm */
73 STOR_REG
, /* scratch register */
74 STOR_VALUE
, /* integer constant */
75 STOR_LABEL
, /* label / jump target */
76 STOR_LABELSYM
, /* label generated from symbol's pointer value */
81 struct storage
*contains
;
82 const unsigned char aliases
[12];
83 #define own_regno aliases[0]
87 enum storage_type type
;
119 struct symbol
*labelsym
;
125 STOR_LABEL_VAL
= (1 << 0),
126 STOR_WANTS_FREE
= (1 << 1),
129 struct symbol_private
{
130 struct storage
*addr
;
145 unsigned int text_len
; /* w/o terminating null */
148 /* stuff for insns */
156 /* stuff for C strings */
158 struct string
*string
;
165 struct function
*current_func
= NULL
;
166 struct textbuf
*unit_post_text
= NULL
;
167 static const char *current_section
;
169 static void emit_comment(const char * fmt
, ...);
170 static void emit_move(struct storage
*src
, struct storage
*dest
,
171 struct symbol
*ctype
, const char *comment
);
172 static int type_is_signed(struct symbol
*sym
);
173 static struct storage
*x86_address_gen(struct expression
*expr
);
174 static struct storage
*x86_symbol_expr(struct symbol
*sym
);
175 static void x86_symbol(struct symbol
*sym
);
176 static struct storage
*x86_statement(struct statement
*stmt
);
177 static struct storage
*x86_expression(struct expression
*expr
);
181 AL
, DL
, CL
, BL
, AH
, DH
, CH
, BH
, // 8-bit
182 AX
, DX
, CX
, BX
, SI
, DI
, BP
, SP
, // 16-bit
183 EAX
, EDX
, ECX
, EBX
, ESI
, EDI
, EBP
, ESP
, // 32-bit
184 EAX_EDX
, ECX_EBX
, ESI_EDI
, // 64-bit
187 /* This works on regno's, reg_info's and hardreg_storage's */
188 #define byte_reg(reg) ((reg) - 16)
189 #define highbyte_reg(reg) ((reg)-12)
190 #define word_reg(reg) ((reg)-8)
192 #define REGINFO(nr, str, conflicts...) [nr] = { .name = str, .aliases = { nr , conflicts } }
194 static struct reg_info reg_info_table
[] = {
195 REGINFO( AL
, "%al", AX
, EAX
, EAX_EDX
),
196 REGINFO( DL
, "%dl", DX
, EDX
, EAX_EDX
),
197 REGINFO( CL
, "%cl", CX
, ECX
, ECX_EBX
),
198 REGINFO( BL
, "%bl", BX
, EBX
, ECX_EBX
),
199 REGINFO( AH
, "%ah", AX
, EAX
, EAX_EDX
),
200 REGINFO( DH
, "%dh", DX
, EDX
, EAX_EDX
),
201 REGINFO( CH
, "%ch", CX
, ECX
, ECX_EBX
),
202 REGINFO( BH
, "%bh", BX
, EBX
, ECX_EBX
),
203 REGINFO( AX
, "%ax", AL
, AH
, EAX
, EAX_EDX
),
204 REGINFO( DX
, "%dx", DL
, DH
, EDX
, EAX_EDX
),
205 REGINFO( CX
, "%cx", CL
, CH
, ECX
, ECX_EBX
),
206 REGINFO( BX
, "%bx", BL
, BH
, EBX
, ECX_EBX
),
207 REGINFO( SI
, "%si", ESI
, ESI_EDI
),
208 REGINFO( DI
, "%di", EDI
, ESI_EDI
),
209 REGINFO( BP
, "%bp", EBP
),
210 REGINFO( SP
, "%sp", ESP
),
211 REGINFO(EAX
, "%eax", AL
, AH
, AX
, EAX_EDX
),
212 REGINFO(EDX
, "%edx", DL
, DH
, DX
, EAX_EDX
),
213 REGINFO(ECX
, "%ecx", CL
, CH
, CX
, ECX_EBX
),
214 REGINFO(EBX
, "%ebx", BL
, BH
, BX
, ECX_EBX
),
215 REGINFO(ESI
, "%esi", SI
, ESI_EDI
),
216 REGINFO(EDI
, "%edi", DI
, ESI_EDI
),
217 REGINFO(EBP
, "%ebp", BP
),
218 REGINFO(ESP
, "%esp", SP
),
219 REGINFO(EAX_EDX
, "%eax:%edx", AL
, AH
, AX
, EAX
, DL
, DH
, DX
, EDX
),
220 REGINFO(ECX_EBX
, "%ecx:%ebx", CL
, CH
, CX
, ECX
, BL
, BH
, BX
, EBX
),
221 REGINFO(ESI_EDI
, "%esi:%edi", SI
, ESI
, DI
, EDI
),
224 #define REGSTORAGE(nr) [nr] = { .type = STOR_REG, .reg = reg_info_table + (nr) }
226 static struct storage hardreg_storage_table
[] = {
227 REGSTORAGE(AL
), REGSTORAGE(DL
), REGSTORAGE(CL
), REGSTORAGE(BL
),
228 REGSTORAGE(AH
), REGSTORAGE(DH
), REGSTORAGE(CH
), REGSTORAGE(BH
),
229 REGSTORAGE(AX
), REGSTORAGE(DX
), REGSTORAGE(CX
), REGSTORAGE(BX
),
230 REGSTORAGE(SI
), REGSTORAGE(DI
), REGSTORAGE(BP
), REGSTORAGE(SP
),
231 REGSTORAGE(EAX
), REGSTORAGE(EDX
), REGSTORAGE(ECX
), REGSTORAGE(EBX
),
232 REGSTORAGE(ESI
), REGSTORAGE(EDI
), REGSTORAGE(EBP
), REGSTORAGE(ESP
),
233 REGSTORAGE(EAX_EDX
), REGSTORAGE(ECX_EBX
), REGSTORAGE(ESI_EDI
),
236 #define REG_EAX (&hardreg_storage_table[EAX])
237 #define REG_ECX (&hardreg_storage_table[ECX])
238 #define REG_EDX (&hardreg_storage_table[EDX])
239 #define REG_ESP (&hardreg_storage_table[ESP])
240 #define REG_DL (&hardreg_storage_table[DL])
241 #define REG_DX (&hardreg_storage_table[DX])
242 #define REG_AL (&hardreg_storage_table[AL])
243 #define REG_AX (&hardreg_storage_table[AX])
245 DECLARE_BITMAP(regs_in_use
, 256);
247 static inline struct storage
* reginfo_reg(struct reg_info
*info
)
249 return hardreg_storage_table
+ info
->own_regno
;
252 struct storage
* get_hardreg(struct storage
*reg
, int clear
)
254 struct reg_info
*info
= reg
->reg
;
255 const unsigned char *aliases
;
258 aliases
= info
->aliases
;
259 while ((regno
= *aliases
++) != NOREG
) {
260 if (test_bit(regno
, regs_in_use
))
263 reg_info_table
[regno
].contains
= NULL
;
265 set_bit(info
->own_regno
, regs_in_use
);
268 fprintf(stderr
, "register %s is busy\n", info
->name
);
269 if (regno
+ reg_info_table
!= info
)
270 fprintf(stderr
, " conflicts with %s\n", reg_info_table
[regno
].name
);
274 void put_reg(struct storage
*reg
)
276 struct reg_info
*info
= reg
->reg
;
277 int regno
= info
->own_regno
;
279 if (test_and_clear_bit(regno
, regs_in_use
))
281 fprintf(stderr
, "freeing already free'd register %s\n", reg_info_table
[regno
].name
);
286 const unsigned char regs
[30];
289 struct regclass regclass_8
= { "8-bit", { AL
, DL
, CL
, BL
, AH
, DH
, CH
, BH
}};
290 struct regclass regclass_16
= { "16-bit", { AX
, DX
, CX
, BX
, SI
, DI
, BP
}};
291 struct regclass regclass_32
= { "32-bit", { EAX
, EDX
, ECX
, EBX
, ESI
, EDI
, EBP
}};
292 struct regclass regclass_64
= { "64-bit", { EAX_EDX
, ECX_EBX
, ESI_EDI
}};
294 struct regclass regclass_32_8
= { "32-bit bytes", { EAX
, EDX
, ECX
, EBX
}};
296 static struct regclass
*get_regclass_bits(int bits
)
299 case 8: return ®class_8
;
300 case 16: return ®class_16
;
301 case 64: return ®class_64
;
302 default: return ®class_32
;
306 static struct regclass
*get_regclass(struct expression
*expr
)
308 return get_regclass_bits(expr
->ctype
->bit_size
);
311 static int register_busy(int regno
)
313 if (!test_bit(regno
, regs_in_use
)) {
314 struct reg_info
*info
= reg_info_table
+ regno
;
315 const unsigned char *regs
= info
->aliases
+1;
317 while ((regno
= *regs
) != NOREG
) {
319 if (test_bit(regno
, regs_in_use
))
328 struct storage
*get_reg(struct regclass
*class)
330 const unsigned char *regs
= class->regs
;
333 while ((regno
= *regs
) != NOREG
) {
335 if (register_busy(regno
))
337 return get_hardreg(hardreg_storage_table
+ regno
, 1);
339 fprintf(stderr
, "Ran out of %s registers\n", class->name
);
343 struct storage
*get_reg_value(struct storage
*value
, struct regclass
*class)
345 struct reg_info
*info
;
348 /* Do we already have it somewhere */
350 if (info
&& info
->contains
== value
) {
351 emit_comment("already have register %s", info
->name
);
352 return get_hardreg(hardreg_storage_table
+ info
->own_regno
, 0);
355 reg
= get_reg(class);
356 emit_move(value
, reg
, value
->ctype
, "reload register");
358 info
->contains
= value
;
363 static struct storage
*temp_from_bits(unsigned int bit_size
)
365 return get_reg(get_regclass_bits(bit_size
));
368 static inline unsigned int pseudo_offset(struct storage
*s
)
370 if (s
->type
!= STOR_PSEUDO
)
371 return 123456; /* intentionally bogus value */
376 static inline unsigned int arg_offset(struct storage
*s
)
378 if (s
->type
!= STOR_ARG
)
379 return 123456; /* intentionally bogus value */
381 /* FIXME: this is wrong wrong wrong */
382 return current_func
->stack_size
+ ((1 + s
->idx
) * 4);
385 static const char *pretty_offset(int ofs
)
387 static char esp_buf
[64];
390 sprintf(esp_buf
, "%d(%%esp)", ofs
);
392 strcpy(esp_buf
, "(%esp)");
397 static void stor_sym_init(struct symbol
*sym
)
399 struct storage
*stor
;
400 struct symbol_private
*priv
;
402 priv
= calloc(1, sizeof(*priv
) + sizeof(*stor
));
404 die("OOM in stor_sym_init");
406 stor
= (struct storage
*) (priv
+ 1);
409 stor
->type
= STOR_SYM
;
413 static const char *stor_op_name(struct storage
*s
)
415 static char name
[32];
419 strcpy(name
, pretty_offset((int) pseudo_offset(s
)));
422 strcpy(name
, pretty_offset((int) arg_offset(s
)));
425 strcpy(name
, show_ident(s
->sym
->ident
));
428 strcpy(name
, s
->reg
->name
);
431 sprintf(name
, "$%Ld", s
->value
);
434 sprintf(name
, "%s.L%d", s
->flags
& STOR_LABEL_VAL
? "$" : "",
438 sprintf(name
, "%s.LS%p", s
->flags
& STOR_LABEL_VAL
? "$" : "",
446 static struct atom
*new_atom(enum atom_type type
)
450 atom
= calloc(1, sizeof(*atom
)); /* TODO: chunked alloc */
459 static inline void push_cstring(struct function
*f
, struct string
*str
,
464 atom
= new_atom(ATOM_CSTR
);
468 add_ptr_list(&f
->str_list
, atom
); /* note: _not_ atom_list */
471 static inline void push_atom(struct function
*f
, struct atom
*atom
)
473 add_ptr_list(&f
->atom_list
, atom
);
476 static void push_text_atom(struct function
*f
, const char *text
)
478 struct atom
*atom
= new_atom(ATOM_TEXT
);
480 atom
->text
= strdup(text
);
481 atom
->text_len
= strlen(text
);
486 static struct storage
*new_storage(enum storage_type type
)
488 struct storage
*stor
;
490 stor
= calloc(1, sizeof(*stor
));
492 die("OOM in new_storage");
499 static struct storage
*stack_alloc(int n_bytes
)
501 struct function
*f
= current_func
;
502 struct storage
*stor
;
506 stor
= new_storage(STOR_PSEUDO
);
507 stor
->type
= STOR_PSEUDO
;
508 stor
->pseudo
= f
->pseudo_nr
;
509 stor
->offset
= f
->stack_size
; /* FIXME: stack req. natural align */
510 stor
->size
= n_bytes
;
511 f
->stack_size
+= n_bytes
;
514 add_ptr_list(&f
->pseudo_list
, stor
);
519 static struct storage
*new_labelsym(struct symbol
*sym
)
521 struct storage
*stor
;
523 stor
= new_storage(STOR_LABELSYM
);
526 stor
->flags
|= STOR_WANTS_FREE
;
527 stor
->labelsym
= sym
;
533 static struct storage
*new_val(long long value
)
535 struct storage
*stor
;
537 stor
= new_storage(STOR_VALUE
);
540 stor
->flags
|= STOR_WANTS_FREE
;
547 static int new_label(void)
549 static int label
= 0;
553 static void textbuf_push(struct textbuf
**buf_p
, const char *text
)
555 struct textbuf
*tmp
, *list
= *buf_p
;
556 unsigned int text_len
= strlen(text
);
557 unsigned int alloc_len
= text_len
+ 1 + sizeof(*list
);
559 tmp
= calloc(1, alloc_len
);
561 die("OOM on textbuf alloc");
563 tmp
->text
= ((void *) tmp
) + sizeof(*tmp
);
564 memcpy(tmp
->text
, text
, text_len
+ 1);
567 /* add to end of list */
572 tmp
->prev
= list
->prev
;
573 tmp
->prev
->next
= tmp
;
581 static void textbuf_emit(struct textbuf
**buf_p
)
583 struct textbuf
*tmp
, *list
= *buf_p
;
587 if (tmp
->next
== tmp
)
590 tmp
->prev
->next
= tmp
->next
;
591 tmp
->next
->prev
= tmp
->prev
;
595 fputs(tmp
->text
, stdout
);
603 static void insn(const char *insn
, struct storage
*op1
, struct storage
*op2
,
604 const char *comment_in
)
606 struct function
*f
= current_func
;
607 struct atom
*atom
= new_atom(ATOM_INSN
);
609 assert(insn
!= NULL
);
611 strcpy(atom
->insn
, insn
);
612 if (comment_in
&& (*comment_in
))
613 strncpy(atom
->comment
, comment_in
,
614 sizeof(atom
->comment
) - 1);
622 static void emit_comment(const char *fmt
, ...)
624 struct function
*f
= current_func
;
625 static char tmpbuf
[100] = "\t# ";
630 i
= vsnprintf(tmpbuf
+3, sizeof(tmpbuf
)-4, fmt
, args
);
634 push_text_atom(f
, tmpbuf
);
637 static void emit_label (int label
, const char *comment
)
639 struct function
*f
= current_func
;
643 sprintf(s
, ".L%d:\n", label
);
645 sprintf(s
, ".L%d:\t\t\t\t\t# %s\n", label
, comment
);
647 push_text_atom(f
, s
);
650 static void emit_labelsym (struct symbol
*sym
, const char *comment
)
652 struct function
*f
= current_func
;
656 sprintf(s
, ".LS%p:\n", sym
);
658 sprintf(s
, ".LS%p:\t\t\t\t# %s\n", sym
, comment
);
660 push_text_atom(f
, s
);
663 void emit_unit_begin(const char *basename
)
665 printf("\t.file\t\"%s\"\n", basename
);
668 void emit_unit_end(void)
670 textbuf_emit(&unit_post_text
);
671 printf("\t.ident\t\"sparse silly x86 backend (built %s)\"\n", __DATE__
);
674 /* conditionally switch sections */
675 static void emit_section(const char *s
)
677 if (s
== current_section
)
679 if (current_section
&& (!strcmp(s
, current_section
)))
686 static void emit_insn_atom(struct function
*f
, struct atom
*atom
)
690 struct storage
*op1
= atom
->op1
;
691 struct storage
*op2
= atom
->op2
;
693 if (atom
->comment
[0])
694 sprintf(comment
, "\t\t# %s", atom
->comment
);
700 strcpy(tmp
, stor_op_name(op1
));
701 sprintf(s
, "\t%s\t%s, %s%s\n",
702 atom
->insn
, tmp
, stor_op_name(op2
), comment
);
703 } else if (atom
->op1
)
704 sprintf(s
, "\t%s\t%s%s%s\n",
705 atom
->insn
, stor_op_name(op1
),
706 comment
[0] ? "\t" : "", comment
);
708 sprintf(s
, "\t%s\t%s%s\n",
710 comment
[0] ? "\t\t" : "", comment
);
712 write(STDOUT_FILENO
, s
, strlen(s
));
715 static void emit_atom_list(struct function
*f
)
719 FOR_EACH_PTR(f
->atom_list
, atom
) {
720 switch (atom
->type
) {
722 ssize_t rc
= write(STDOUT_FILENO
, atom
->text
,
724 (void) rc
; /* FIXME */
728 emit_insn_atom(f
, atom
);
737 static void emit_string_list(struct function
*f
)
741 emit_section(".section\t.rodata");
743 FOR_EACH_PTR(f
->str_list
, atom
) {
744 /* FIXME: escape " in string */
745 printf(".L%d:\n", atom
->label
);
746 printf("\t.string\t%s\n", show_string(atom
->string
));
752 static void func_cleanup(struct function
*f
)
754 struct storage
*stor
;
757 FOR_EACH_PTR(f
->pseudo_list
, stor
) {
761 FOR_EACH_PTR(f
->atom_list
, atom
) {
762 if ((atom
->type
== ATOM_TEXT
) && (atom
->text
))
764 if (atom
->op1
&& (atom
->op1
->flags
& STOR_WANTS_FREE
))
766 if (atom
->op2
&& (atom
->op2
->flags
& STOR_WANTS_FREE
))
771 free_ptr_list(&f
->pseudo_list
);
775 /* function prologue */
776 static void emit_func_pre(struct symbol
*sym
)
780 unsigned int i
, argc
= 0, alloc_len
;
782 struct symbol_private
*privbase
;
783 struct storage
*storage_base
;
784 struct symbol
*base_type
= sym
->ctype
.base_type
;
786 FOR_EACH_PTR(base_type
->arguments
, arg
) {
792 (argc
* sizeof(struct symbol
*)) +
793 (argc
* sizeof(struct symbol_private
)) +
794 (argc
* sizeof(struct storage
));
795 mem
= calloc(1, alloc_len
);
797 die("OOM on func info");
799 f
= (struct function
*) mem
;
801 f
->argv
= (struct symbol
**) mem
;
802 mem
+= (argc
* sizeof(struct symbol
*));
803 privbase
= (struct symbol_private
*) mem
;
804 mem
+= (argc
* sizeof(struct symbol_private
));
805 storage_base
= (struct storage
*) mem
;
808 f
->ret_target
= new_label();
811 FOR_EACH_PTR(base_type
->arguments
, arg
) {
813 arg
->aux
= &privbase
[i
];
814 storage_base
[i
].type
= STOR_ARG
;
815 storage_base
[i
].idx
= i
;
816 privbase
[i
].addr
= &storage_base
[i
];
820 assert(current_func
== NULL
);
824 /* function epilogue */
825 static void emit_func_post(struct symbol
*sym
)
827 const char *name
= show_ident(sym
->ident
);
828 struct function
*f
= current_func
;
829 int stack_size
= f
->stack_size
;
834 /* function prologue */
835 emit_section(".text");
836 if ((sym
->ctype
.modifiers
& MOD_STATIC
) == 0)
837 printf(".globl %s\n", name
);
838 printf("\t.type\t%s, @function\n", name
);
839 printf("%s:\n", name
);
842 char pseudo_const
[16];
844 sprintf(pseudo_const
, "$%d", stack_size
);
845 printf("\tsubl\t%s, %%esp\n", pseudo_const
);
848 /* function epilogue */
850 /* jump target for 'return' statements */
851 emit_label(f
->ret_target
, NULL
);
856 val
= new_storage(STOR_VALUE
);
857 val
->value
= (long long) (stack_size
);
858 val
->flags
= STOR_WANTS_FREE
;
860 insn("addl", val
, REG_ESP
, NULL
);
863 insn("ret", NULL
, NULL
, NULL
);
865 /* output everything to stdout */
866 fflush(stdout
); /* paranoia; needed? */
869 /* function footer */
870 name
= show_ident(sym
->ident
);
871 printf("\t.size\t%s, .-%s\n", name
, name
);
877 /* emit object (a.k.a. variable, a.k.a. data) prologue */
878 static void emit_object_pre(const char *name
, unsigned long modifiers
,
879 unsigned long alignment
, unsigned int byte_size
)
881 if ((modifiers
& MOD_STATIC
) == 0)
882 printf(".globl %s\n", name
);
883 emit_section(".data");
885 printf("\t.align %lu\n", alignment
);
886 printf("\t.type\t%s, @object\n", name
);
887 printf("\t.size\t%s, %d\n", name
, byte_size
);
888 printf("%s:\n", name
);
891 /* emit value (only) for an initializer scalar */
892 static void emit_scalar(struct expression
*expr
, unsigned int bit_size
)
897 assert(expr
->type
== EXPR_VALUE
);
899 if (expr
->value
== 0ULL) {
900 printf("\t.zero\t%d\n", bit_size
/ 8);
904 ll
= (long long) expr
->value
;
907 case 8: type
= "byte"; ll
= (char) ll
; break;
908 case 16: type
= "value"; ll
= (short) ll
; break;
909 case 32: type
= "long"; ll
= (int) ll
; break;
910 case 64: type
= "quad"; break;
911 default: type
= NULL
; break;
914 assert(type
!= NULL
);
916 printf("\t.%s\t%Ld\n", type
, ll
);
919 static void emit_global_noinit(const char *name
, unsigned long modifiers
,
920 unsigned long alignment
, unsigned int byte_size
)
924 if (modifiers
& MOD_STATIC
) {
925 sprintf(s
, "\t.local\t%s\n", name
);
926 textbuf_push(&unit_post_text
, s
);
929 sprintf(s
, "\t.comm\t%s,%d,%lu\n", name
, byte_size
, alignment
);
931 sprintf(s
, "\t.comm\t%s,%d\n", name
, byte_size
);
932 textbuf_push(&unit_post_text
, s
);
935 static int ea_current
, ea_last
;
937 static void emit_initializer(struct symbol
*sym
,
938 struct expression
*expr
)
940 int distance
= ea_current
- ea_last
- 1;
943 printf("\t.zero\t%d\n", (sym
->bit_size
/ 8) * distance
);
945 if (expr
->type
== EXPR_VALUE
) {
946 struct symbol
*base_type
= sym
->ctype
.base_type
;
947 assert(base_type
!= NULL
);
949 emit_scalar(expr
, sym
->bit_size
/ get_expression_value(base_type
->array_size
));
952 if (expr
->type
!= EXPR_INITIALIZER
)
955 assert(0); /* FIXME */
958 static int sort_array_cmp(const struct expression
*a
,
959 const struct expression
*b
)
961 int a_ofs
= 0, b_ofs
= 0;
963 if (a
->type
== EXPR_POS
)
964 a_ofs
= (int) a
->init_offset
;
965 if (b
->type
== EXPR_POS
)
966 b_ofs
= (int) b
->init_offset
;
968 return a_ofs
- b_ofs
;
971 /* move to front-end? */
972 static void sort_array(struct expression
*expr
)
974 struct expression
*entry
, **list
;
975 unsigned int elem
, sorted
, i
;
978 FOR_EACH_PTR(expr
->expr_list
, entry
) {
985 list
= malloc(sizeof(entry
) * elem
);
987 die("OOM in sort_array");
989 /* this code is no doubt evil and ignores EXPR_INDEX possibly
990 * to its detriment and other nasty things. improvements
995 FOR_EACH_PTR(expr
->expr_list
, entry
) {
996 if ((entry
->type
== EXPR_POS
) || (entry
->type
== EXPR_VALUE
)) {
997 /* add entry to list[], in sorted order */
1004 for (i
= 0; i
< sorted
; i
++)
1005 if (sort_array_cmp(entry
, list
[i
]) <= 0)
1008 /* If inserting into the middle of list[]
1009 * instead of appending, we memmove.
1010 * This is ugly, but thankfully
1011 * uncommon. Input data with tons of
1012 * entries very rarely have explicit
1013 * offsets. convert to qsort eventually...
1016 memmove(&list
[i
+ 1], &list
[i
],
1017 (sorted
- i
) * sizeof(entry
));
1025 FOR_EACH_PTR(expr
->expr_list
, entry
) {
1026 if ((entry
->type
== EXPR_POS
) || (entry
->type
== EXPR_VALUE
))
1027 __list
->list
[__i
] = list
[i
++];
1032 static void emit_array(struct symbol
*sym
)
1034 struct symbol
*base_type
= sym
->ctype
.base_type
;
1035 struct expression
*expr
= sym
->initializer
;
1036 struct expression
*entry
;
1038 assert(base_type
!= NULL
);
1044 emit_object_pre(show_ident(sym
->ident
), sym
->ctype
.modifiers
,
1045 sym
->ctype
.alignment
,
1050 FOR_EACH_PTR(expr
->expr_list
, entry
) {
1051 if (entry
->type
== EXPR_VALUE
) {
1053 emit_initializer(sym
, entry
);
1054 ea_last
= ea_current
;
1055 } else if (entry
->type
== EXPR_POS
) {
1057 entry
->init_offset
/ (base_type
->bit_size
/ 8);
1058 emit_initializer(sym
, entry
->init_expr
);
1059 ea_last
= ea_current
;
1064 void emit_one_symbol(struct symbol
*sym
)
1069 static void emit_copy(struct storage
*dest
, struct storage
*src
,
1070 struct symbol
*ctype
)
1072 struct storage
*reg
= NULL
;
1073 unsigned int bit_size
;
1075 /* FIXME: Bitfield copy! */
1077 bit_size
= src
->size
* 8;
1080 if ((src
->type
== STOR_ARG
) && (bit_size
< 32))
1083 reg
= temp_from_bits(bit_size
);
1084 emit_move(src
, reg
, ctype
, "begin copy ..");
1086 bit_size
= dest
->size
* 8;
1089 if ((dest
->type
== STOR_ARG
) && (bit_size
< 32))
1092 emit_move(reg
, dest
, ctype
, ".... end copy");
1096 static void emit_store(struct expression
*dest_expr
, struct storage
*dest
,
1097 struct storage
*src
, int bits
)
1099 /* FIXME: Bitfield store! */
1100 printf("\tst.%d\t\tv%d,[v%d]\n", bits
, src
->pseudo
, dest
->pseudo
);
1103 static void emit_scalar_noinit(struct symbol
*sym
)
1105 emit_global_noinit(show_ident(sym
->ident
),
1106 sym
->ctype
.modifiers
, sym
->ctype
.alignment
,
1111 static void emit_array_noinit(struct symbol
*sym
)
1113 emit_global_noinit(show_ident(sym
->ident
),
1114 sym
->ctype
.modifiers
, sym
->ctype
.alignment
,
1115 get_expression_value(sym
->array_size
) * (sym
->bit_size
/ 8));
1119 static const char *opbits(const char *insn
, unsigned int bits
)
1121 static char opbits_str
[32];
1125 case 8: c
= 'b'; break;
1126 case 16: c
= 'w'; break;
1127 case 32: c
= 'l'; break;
1128 case 64: c
= 'q'; break;
1129 default: assert(0); break;
1132 sprintf(opbits_str
, "%s%c", insn
, c
);
1137 static void emit_move(struct storage
*src
, struct storage
*dest
,
1138 struct symbol
*ctype
, const char *comment
)
1141 unsigned int is_signed
;
1142 unsigned int is_dest
= (src
->type
== STOR_REG
);
1146 bits
= ctype
->bit_size
;
1147 is_signed
= type_is_signed(ctype
);
1154 * Are we moving from a register to a register?
1155 * Make the new reg to be the "cache".
1157 if ((dest
->type
== STOR_REG
) && (src
->type
== STOR_REG
)) {
1158 struct storage
*backing
;
1164 backing
= src
->reg
->contains
;
1166 /* Is it still valid? */
1167 if (backing
->reg
!= src
->reg
)
1170 backing
->reg
= dest
->reg
;
1172 dest
->reg
->contains
= backing
;
1173 insn("mov", src
, dest
, NULL
);
1178 * Are we moving to a register from a non-reg?
1180 * See if we have the non-reg source already cached
1183 if (dest
->type
== STOR_REG
) {
1185 struct reg_info
*info
= src
->reg
;
1186 if (info
->contains
== src
) {
1187 src
= reginfo_reg(info
);
1191 dest
->reg
->contains
= src
;
1192 src
->reg
= dest
->reg
;
1195 if (src
->type
== STOR_REG
) {
1196 /* We could just mark the register dirty here and do lazy store.. */
1197 src
->reg
->contains
= dest
;
1198 dest
->reg
= src
->reg
;
1201 if ((bits
== 8) || (bits
== 16)) {
1205 opname
= is_signed
? "movsx" : "movzx";
1209 insn(opbits(opname
, bits
), src
, dest
, comment
);
1212 static struct storage
*emit_compare(struct expression
*expr
)
1214 struct storage
*left
= x86_expression(expr
->left
);
1215 struct storage
*right
= x86_expression(expr
->right
);
1216 struct storage
*reg1
, *reg2
;
1217 struct storage
*new, *val
;
1218 const char *opname
= NULL
;
1219 unsigned int right_bits
= expr
->right
->ctype
->bit_size
;
1222 case '<': opname
= "setl"; break;
1223 case '>': opname
= "setg"; break;
1225 opname
= "setle"; break;
1227 opname
= "setge"; break;
1228 case SPECIAL_EQUAL
: opname
= "sete"; break;
1229 case SPECIAL_NOTEQUAL
: opname
= "setne"; break;
1230 case SPECIAL_UNSIGNED_LT
:
1231 opname
= "setb"; break;
1232 case SPECIAL_UNSIGNED_GT
:
1233 opname
= "seta"; break;
1234 case SPECIAL_UNSIGNED_LTE
:
1235 opname
= "setb"; break;
1236 case SPECIAL_UNSIGNED_GTE
:
1237 opname
= "setae"; break;
1244 val
= new_storage(STOR_VALUE
);
1245 val
->flags
= STOR_WANTS_FREE
;
1247 reg1
= get_reg(®class_32_8
);
1248 emit_move(val
, reg1
, NULL
, NULL
);
1250 /* move op1 into EAX */
1251 reg2
= get_reg_value(left
, get_regclass(expr
->left
));
1253 /* perform comparison, RHS (op1, right) and LHS (op2, EAX) */
1254 insn(opbits("cmp", right_bits
), right
, reg2
, NULL
);
1257 /* store result of operation, 0 or 1, in DL using SETcc */
1258 insn(opname
, byte_reg(reg1
), NULL
, NULL
);
1260 /* finally, store the result (DL) in a new pseudo / stack slot */
1261 new = stack_alloc(4);
1262 emit_move(reg1
, new, NULL
, "end EXPR_COMPARE");
1268 static struct storage
*emit_value(struct expression
*expr
)
1270 #if 0 /* old and slow way */
1271 struct storage
*new = stack_alloc(4);
1272 struct storage
*val
;
1274 val
= new_storage(STOR_VALUE
);
1275 val
->value
= (long long) expr
->value
;
1276 val
->flags
= STOR_WANTS_FREE
;
1277 insn("movl", val
, new, NULL
);
1281 struct storage
*val
;
1283 val
= new_storage(STOR_VALUE
);
1284 val
->value
= (long long) expr
->value
;
1286 return val
; /* FIXME: memory leak */
1290 static struct storage
*emit_divide(struct expression
*expr
, struct storage
*left
, struct storage
*right
)
1292 struct storage
*eax_edx
;
1293 struct storage
*reg
, *new;
1294 struct storage
*val
= new_storage(STOR_VALUE
);
1296 emit_comment("begin DIVIDE");
1297 eax_edx
= get_hardreg(hardreg_storage_table
+ EAX_EDX
, 1);
1300 val
= new_storage(STOR_VALUE
);
1301 val
->flags
= STOR_WANTS_FREE
;
1302 emit_move(val
, REG_EDX
, NULL
, NULL
);
1304 new = stack_alloc(expr
->ctype
->bit_size
/ 8);
1306 /* EAX is dividend */
1307 emit_move(left
, REG_EAX
, NULL
, NULL
);
1309 reg
= get_reg_value(right
, ®class_32
);
1312 insn("div", reg
, REG_EAX
, NULL
);
1316 if (expr
->op
== '%')
1318 emit_move(reg
, new, NULL
, NULL
);
1321 emit_comment("end DIVIDE");
1325 static struct storage
*emit_binop(struct expression
*expr
)
1327 struct storage
*left
= x86_expression(expr
->left
);
1328 struct storage
*right
= x86_expression(expr
->right
);
1329 struct storage
*new;
1330 struct storage
*dest
, *src
;
1331 const char *opname
= NULL
;
1332 const char *suffix
= NULL
;
1336 /* Divides have special register constraints */
1337 if ((expr
->op
== '/') || (expr
->op
== '%'))
1338 return emit_divide(expr
, left
, right
);
1340 is_signed
= type_is_signed(expr
->ctype
);
1358 case SPECIAL_LEFTSHIFT
:
1361 case SPECIAL_RIGHTSHIFT
:
1373 case SPECIAL_LOGICAL_AND
:
1374 warn(expr
->pos
, "bogus bitwise and for logical op (should use '2*setne + and' or something)");
1377 case SPECIAL_LOGICAL_OR
:
1378 warn(expr
->pos
, "bogus bitwise or for logical op (should use 'or + setne' or something)");
1382 error(expr
->pos
, "unhandled binop '%s'\n", show_special(expr
->op
));
1386 dest
= get_reg_value(right
, ®class_32
);
1387 src
= get_reg_value(left
, ®class_32
);
1388 switch (expr
->ctype
->bit_size
) {
1399 suffix
= "q"; /* FIXME */
1406 snprintf(opstr
, sizeof(opstr
), "%s%s", opname
, suffix
);
1409 insn(opstr
, src
, dest
, NULL
);
1412 /* store result in new pseudo / stack slot */
1413 new = stack_alloc(expr
->ctype
->bit_size
/ 8);
1414 emit_move(dest
, new, NULL
, "end EXPR_BINOP");
1421 static int emit_conditional_test(struct storage
*val
)
1423 struct storage
*reg
;
1424 struct storage
*target_val
;
1427 /* load result into EAX */
1428 emit_comment("begin if/conditional");
1429 reg
= get_reg_value(val
, ®class_32
);
1431 /* compare result with zero */
1432 insn("test", reg
, reg
, NULL
);
1435 /* create conditional-failed label to jump to */
1436 target_false
= new_label();
1437 target_val
= new_storage(STOR_LABEL
);
1438 target_val
->label
= target_false
;
1439 target_val
->flags
= STOR_WANTS_FREE
;
1440 insn("jz", target_val
, NULL
, NULL
);
1442 return target_false
;
1445 static int emit_conditional_end(int target_false
)
1447 struct storage
*cond_end_st
;
1450 /* finished generating code for if-true statement.
1451 * add a jump-to-end jump to avoid falling through
1452 * to the if-false statement code.
1454 cond_end
= new_label();
1455 cond_end_st
= new_storage(STOR_LABEL
);
1456 cond_end_st
->label
= cond_end
;
1457 cond_end_st
->flags
= STOR_WANTS_FREE
;
1458 insn("jmp", cond_end_st
, NULL
, NULL
);
1460 /* if we have both if-true and if-false statements,
1461 * the failed-conditional case will fall through to here
1463 emit_label(target_false
, NULL
);
1468 static void emit_if_conditional(struct statement
*stmt
)
1470 struct storage
*val
;
1473 /* emit test portion of conditional */
1474 val
= x86_expression(stmt
->if_conditional
);
1475 cond_end
= emit_conditional_test(val
);
1477 /* emit if-true statement */
1478 x86_statement(stmt
->if_true
);
1480 /* emit if-false statement, if present */
1481 if (stmt
->if_false
) {
1482 cond_end
= emit_conditional_end(cond_end
);
1483 x86_statement(stmt
->if_false
);
1486 /* end of conditional; jump target for if-true branch */
1487 emit_label(cond_end
, "end if");
1490 static struct storage
*emit_inc_dec(struct expression
*expr
, int postop
)
1492 struct storage
*addr
= x86_address_gen(expr
->unop
);
1493 struct storage
*retval
;
1496 strcpy(opname
, opbits(expr
->op
== SPECIAL_INCREMENT
? "inc" : "dec",
1497 expr
->ctype
->bit_size
));
1500 struct storage
*new = stack_alloc(4);
1502 emit_copy(new, addr
, expr
->unop
->ctype
);
1508 insn(opname
, addr
, NULL
, NULL
);
1513 static struct storage
*emit_postop(struct expression
*expr
)
1515 return emit_inc_dec(expr
, 1);
1518 static struct storage
*emit_return_stmt(struct statement
*stmt
)
1520 struct function
*f
= current_func
;
1521 struct expression
*expr
= stmt
->ret_value
;
1522 struct storage
*val
= NULL
, *jmplbl
;
1524 if (expr
&& expr
->ctype
) {
1525 val
= x86_expression(expr
);
1526 assert(val
!= NULL
);
1527 emit_move(val
, REG_EAX
, expr
->ctype
, "return");
1530 jmplbl
= new_storage(STOR_LABEL
);
1531 jmplbl
->flags
|= STOR_WANTS_FREE
;
1532 jmplbl
->label
= f
->ret_target
;
1533 insn("jmp", jmplbl
, NULL
, NULL
);
1538 static struct storage
*emit_conditional_expr(struct expression
*expr
)
1540 struct storage
*cond
, *true = NULL
, *false = NULL
;
1541 struct storage
*new = stack_alloc(expr
->ctype
->bit_size
/ 8);
1542 int target_false
, cond_end
;
1544 /* evaluate conditional */
1545 cond
= x86_expression(expr
->conditional
);
1546 target_false
= emit_conditional_test(cond
);
1548 /* handle if-true part of the expression */
1549 if (!expr
->cond_true
)
1552 true = x86_expression(expr
->cond_true
);
1554 emit_copy(new, true, expr
->ctype
);
1556 cond_end
= emit_conditional_end(target_false
);
1558 /* handle if-false part of the expression */
1559 false = x86_expression(expr
->cond_false
);
1561 emit_copy(new, false, expr
->ctype
);
1563 /* end of conditional; jump target for if-true branch */
1564 emit_label(cond_end
, "end conditional");
1569 static struct storage
*emit_select_expr(struct expression
*expr
)
1571 struct storage
*cond
= x86_expression(expr
->conditional
);
1572 struct storage
*true = x86_expression(expr
->cond_true
);
1573 struct storage
*false = x86_expression(expr
->cond_false
);
1574 struct storage
*reg_cond
, *reg_true
, *reg_false
;
1575 struct storage
*new = stack_alloc(4);
1577 emit_comment("begin SELECT");
1578 reg_cond
= get_reg_value(cond
, get_regclass(expr
->conditional
));
1579 reg_true
= reg_cond
;
1581 reg_true
= get_reg_value(true, get_regclass(expr
));
1583 reg_false
= get_reg_value(false, get_regclass(expr
));
1586 * Do the actual select: check the conditional for zero,
1587 * move false over true if zero
1589 insn("test", reg_cond
, reg_cond
, NULL
);
1590 insn("cmovz", reg_false
, reg_true
, NULL
);
1593 emit_move(reg_true
, new, expr
->ctype
, NULL
);
1598 emit_comment("end SELECT");
1602 static struct storage
*emit_symbol_expr_init(struct symbol
*sym
)
1604 struct expression
*expr
= sym
->initializer
;
1605 struct symbol_private
*priv
= sym
->aux
;
1608 priv
= calloc(1, sizeof(*priv
));
1612 struct storage
*new = stack_alloc(4);
1613 fprintf(stderr
, "FIXME! no value for symbol %s. creating pseudo %d (stack offset %d)\n",
1614 show_ident(sym
->ident
),
1615 new->pseudo
, new->pseudo
* 4);
1618 priv
->addr
= x86_expression(expr
);
1625 static struct storage
*emit_string_expr(struct expression
*expr
)
1627 struct function
*f
= current_func
;
1628 int label
= new_label();
1629 struct storage
*new;
1631 push_cstring(f
, expr
->string
, label
);
1633 new = new_storage(STOR_LABEL
);
1635 new->flags
= STOR_LABEL_VAL
| STOR_WANTS_FREE
;
1639 static struct storage
*emit_cast_expr(struct expression
*expr
)
1641 struct symbol
*old_type
, *new_type
;
1642 struct storage
*op
= x86_expression(expr
->cast_expression
);
1643 int oldbits
, newbits
;
1644 struct storage
*new;
1646 old_type
= expr
->cast_expression
->ctype
;
1647 new_type
= expr
->cast_type
;
1649 oldbits
= old_type
->bit_size
;
1650 newbits
= new_type
->bit_size
;
1651 if (oldbits
>= newbits
)
1654 emit_move(op
, REG_EAX
, old_type
, "begin cast ..");
1656 new = stack_alloc(newbits
/ 8);
1657 emit_move(REG_EAX
, new, new_type
, ".... end cast");
1662 static struct storage
*emit_regular_preop(struct expression
*expr
)
1664 struct storage
*target
= x86_expression(expr
->unop
);
1665 struct storage
*val
, *new = stack_alloc(4);
1666 const char *opname
= NULL
;
1670 val
= new_storage(STOR_VALUE
);
1671 val
->flags
= STOR_WANTS_FREE
;
1672 emit_move(val
, REG_EDX
, NULL
, NULL
);
1673 emit_move(target
, REG_EAX
, expr
->unop
->ctype
, NULL
);
1674 insn("test", REG_EAX
, REG_EAX
, NULL
);
1675 insn("setz", REG_DL
, NULL
, NULL
);
1676 emit_move(REG_EDX
, new, expr
->unop
->ctype
, NULL
);
1684 emit_move(target
, REG_EAX
, expr
->unop
->ctype
, NULL
);
1685 insn(opname
, REG_EAX
, NULL
, NULL
);
1686 emit_move(REG_EAX
, new, expr
->unop
->ctype
, NULL
);
1696 static void emit_case_statement(struct statement
*stmt
)
1698 emit_labelsym(stmt
->case_label
, NULL
);
1699 x86_statement(stmt
->case_statement
);
1702 static void emit_switch_statement(struct statement
*stmt
)
1704 struct storage
*val
= x86_expression(stmt
->switch_expression
);
1705 struct symbol
*sym
, *default_sym
= NULL
;
1706 struct storage
*labelsym
, *label
;
1709 emit_move(val
, REG_EAX
, stmt
->switch_expression
->ctype
, "begin case");
1712 * This is where a _real_ back-end would go through the
1713 * cases to decide whether to use a lookup table or a
1714 * series of comparisons etc
1716 FOR_EACH_PTR(stmt
->switch_case
->symbol_list
, sym
) {
1717 struct statement
*case_stmt
= sym
->stmt
;
1718 struct expression
*expr
= case_stmt
->case_expression
;
1719 struct expression
*to
= case_stmt
->case_to
;
1727 struct storage
*case_val
= new_val(expr
->value
);
1729 assert (expr
->type
== EXPR_VALUE
);
1731 insn("cmpl", case_val
, REG_EAX
, NULL
);
1734 labelsym
= new_labelsym(sym
);
1735 insn("je", labelsym
, NULL
, NULL
);
1739 label
= new_storage(STOR_LABEL
);
1740 label
->flags
|= STOR_WANTS_FREE
;
1741 label
->label
= next_test
= new_label();
1743 /* FIXME: signed/unsigned */
1744 insn("jl", label
, NULL
, NULL
);
1746 case_val
= new_val(to
->value
);
1747 insn("cmpl", case_val
, REG_EAX
, NULL
);
1749 /* TODO: implement and use refcounting... */
1750 label
= new_storage(STOR_LABEL
);
1751 label
->flags
|= STOR_WANTS_FREE
;
1752 label
->label
= next_test
;
1754 /* FIXME: signed/unsigned */
1755 insn("jg", label
, NULL
, NULL
);
1757 labelsym
= new_labelsym(sym
);
1758 insn("jmp", labelsym
, NULL
, NULL
);
1760 emit_label(next_test
, NULL
);
1766 labelsym
= new_labelsym(default_sym
);
1767 insn("jmp", labelsym
, NULL
, "default");
1769 label
= new_storage(STOR_LABEL
);
1770 label
->flags
|= STOR_WANTS_FREE
;
1771 label
->label
= switch_end
= new_label();
1772 insn("jmp", label
, NULL
, "goto end of switch");
1775 x86_statement(stmt
->switch_statement
);
1777 if (stmt
->switch_break
->used
)
1778 emit_labelsym(stmt
->switch_break
, NULL
);
1781 emit_label(switch_end
, NULL
);
1784 static void x86_struct_member(struct symbol
*sym
, void *data
, int flags
)
1786 if (flags
& ITERATE_FIRST
)
1788 printf("%s:%d:%ld at offset %ld", show_ident(sym
->ident
), sym
->bit_size
, sym
->ctype
.alignment
, sym
->offset
);
1789 if (sym
->fieldwidth
)
1790 printf("[%d..%d]", sym
->bit_offset
, sym
->bit_offset
+sym
->fieldwidth
-1);
1791 if (flags
& ITERATE_LAST
)
1797 static void x86_symbol(struct symbol
*sym
)
1799 struct symbol
*type
;
1804 type
= sym
->ctype
.base_type
;
1809 * Show actual implementation information
1811 switch (type
->type
) {
1814 if (sym
->initializer
)
1817 emit_array_noinit(sym
);
1821 if (sym
->initializer
) {
1822 emit_object_pre(show_ident(sym
->ident
),
1823 sym
->ctype
.modifiers
,
1824 sym
->ctype
.alignment
,
1826 emit_scalar(sym
->initializer
, sym
->bit_size
);
1829 emit_scalar_noinit(sym
);
1833 symbol_iterate(type
->symbol_list
, x86_struct_member
, NULL
);
1837 symbol_iterate(type
->symbol_list
, x86_struct_member
, NULL
);
1841 struct statement
*stmt
= type
->stmt
;
1844 x86_statement(stmt
);
1845 emit_func_post(sym
);
1854 if (sym
->initializer
&& (type
->type
!= SYM_BASETYPE
) &&
1855 (type
->type
!= SYM_ARRAY
)) {
1857 x86_expression(sym
->initializer
);
1861 static void x86_symbol_init(struct symbol
*sym
);
1863 static void x86_symbol_decl(struct symbol_list
*syms
)
1866 FOR_EACH_PTR(syms
, sym
) {
1867 x86_symbol_init(sym
);
1871 static void loopstk_push(int cont_lbl
, int loop_bottom_lbl
)
1873 struct function
*f
= current_func
;
1874 struct loop_stack
*ls
;
1876 ls
= malloc(sizeof(*ls
));
1877 ls
->continue_lbl
= cont_lbl
;
1878 ls
->loop_bottom_lbl
= loop_bottom_lbl
;
1879 ls
->next
= f
->loop_stack
;
1883 static void loopstk_pop(void)
1885 struct function
*f
= current_func
;
1886 struct loop_stack
*ls
;
1888 assert(f
->loop_stack
!= NULL
);
1890 f
->loop_stack
= f
->loop_stack
->next
;
1894 static int loopstk_break(void)
1896 return current_func
->loop_stack
->loop_bottom_lbl
;
1899 static int loopstk_continue(void)
1901 return current_func
->loop_stack
->continue_lbl
;
1904 static void emit_loop(struct statement
*stmt
)
1906 struct statement
*pre_statement
= stmt
->iterator_pre_statement
;
1907 struct expression
*pre_condition
= stmt
->iterator_pre_condition
;
1908 struct statement
*statement
= stmt
->iterator_statement
;
1909 struct statement
*post_statement
= stmt
->iterator_post_statement
;
1910 struct expression
*post_condition
= stmt
->iterator_post_condition
;
1911 int loop_top
= 0, loop_bottom
, loop_continue
;
1912 int have_bottom
= 0;
1913 struct storage
*val
;
1915 loop_bottom
= new_label();
1916 loop_continue
= new_label();
1917 loopstk_push(loop_continue
, loop_bottom
);
1919 x86_symbol_decl(stmt
->iterator_syms
);
1920 x86_statement(pre_statement
);
1921 if (pre_condition
) {
1922 if (pre_condition
->type
== EXPR_VALUE
) {
1923 if (!pre_condition
->value
) {
1924 struct storage
*lbv
;
1925 lbv
= new_storage(STOR_LABEL
);
1926 lbv
->label
= loop_bottom
;
1927 lbv
->flags
= STOR_WANTS_FREE
;
1928 insn("jmp", lbv
, NULL
, "go to loop bottom");
1932 struct storage
*lbv
= new_storage(STOR_LABEL
);
1933 lbv
->label
= loop_bottom
;
1934 lbv
->flags
= STOR_WANTS_FREE
;
1937 val
= x86_expression(pre_condition
);
1939 emit_move(val
, REG_EAX
, NULL
, "loop pre condition");
1940 insn("test", REG_EAX
, REG_EAX
, NULL
);
1941 insn("jz", lbv
, NULL
, NULL
);
1944 if (!post_condition
|| post_condition
->type
!= EXPR_VALUE
|| post_condition
->value
) {
1945 loop_top
= new_label();
1946 emit_label(loop_top
, "loop top");
1948 x86_statement(statement
);
1949 if (stmt
->iterator_continue
->used
)
1950 emit_label(loop_continue
, "'continue' iterator");
1951 x86_statement(post_statement
);
1952 if (!post_condition
) {
1953 struct storage
*lbv
= new_storage(STOR_LABEL
);
1954 lbv
->label
= loop_top
;
1955 lbv
->flags
= STOR_WANTS_FREE
;
1956 insn("jmp", lbv
, NULL
, "go to loop top");
1957 } else if (post_condition
->type
== EXPR_VALUE
) {
1958 if (post_condition
->value
) {
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");
1965 struct storage
*lbv
= new_storage(STOR_LABEL
);
1966 lbv
->label
= loop_top
;
1967 lbv
->flags
= STOR_WANTS_FREE
;
1969 val
= x86_expression(post_condition
);
1971 emit_move(val
, REG_EAX
, NULL
, "loop post condition");
1972 insn("test", REG_EAX
, REG_EAX
, NULL
);
1973 insn("jnz", lbv
, NULL
, NULL
);
1975 if (have_bottom
|| stmt
->iterator_break
->used
)
1976 emit_label(loop_bottom
, "loop bottom");
1982 * Print out a statement
1984 static struct storage
*x86_statement(struct statement
*stmt
)
1988 switch (stmt
->type
) {
1990 return emit_return_stmt(stmt
);
1991 case STMT_COMPOUND
: {
1992 struct statement
*s
;
1993 struct storage
*last
= NULL
;
1995 x86_symbol_decl(stmt
->syms
);
1996 FOR_EACH_PTR(stmt
->stmts
, s
) {
1997 last
= x86_statement(s
);
2003 case STMT_EXPRESSION
:
2004 return x86_expression(stmt
->expression
);
2006 emit_if_conditional(stmt
);
2010 emit_case_statement(stmt
);
2013 emit_switch_statement(stmt
);
2024 printf(".L%p:\n", stmt
->label_identifier
);
2025 x86_statement(stmt
->label_statement
);
2029 if (stmt
->goto_expression
) {
2030 struct storage
*val
= x86_expression(stmt
->goto_expression
);
2031 printf("\tgoto *v%d\n", val
->pseudo
);
2032 } else if (!strcmp("break", show_ident(stmt
->goto_label
->ident
))) {
2033 struct storage
*lbv
= new_storage(STOR_LABEL
);
2034 lbv
->label
= loopstk_break();
2035 lbv
->flags
= STOR_WANTS_FREE
;
2036 insn("jmp", lbv
, NULL
, "'break'; go to loop bottom");
2037 } else if (!strcmp("continue", show_ident(stmt
->goto_label
->ident
))) {
2038 struct storage
*lbv
= new_storage(STOR_LABEL
);
2039 lbv
->label
= loopstk_continue();
2040 lbv
->flags
= STOR_WANTS_FREE
;
2041 insn("jmp", lbv
, NULL
, "'continue'; go to loop top");
2043 struct storage
*labelsym
= new_labelsym(stmt
->goto_label
);
2044 insn("jmp", labelsym
, NULL
, NULL
);
2048 printf("\tasm( .... )\n");
2054 static struct storage
*x86_call_expression(struct expression
*expr
)
2056 struct function
*f
= current_func
;
2057 struct symbol
*direct
;
2058 struct expression
*arg
, *fn
;
2059 struct storage
*retval
, *fncall
;
2064 warn(expr
->pos
, "\tcall with no type!");
2069 FOR_EACH_PTR_REVERSE(expr
->args
, arg
) {
2070 struct storage
*new = x86_expression(arg
);
2071 int size
= arg
->ctype
->bit_size
;
2074 * FIXME: i386 SysV ABI dictates that values
2075 * smaller than 32 bits should be placed onto
2076 * the stack as 32-bit objects. We should not
2077 * blindly do a 32-bit push on objects smaller
2082 insn("pushl", new, NULL
,
2083 !framesize
? "begin function call" : NULL
);
2085 framesize
+= size
>> 3;
2086 } END_FOR_EACH_PTR_REVERSE
;
2090 /* Remove dereference, if any */
2092 if (fn
->type
== EXPR_PREOP
) {
2093 if (fn
->unop
->type
== EXPR_SYMBOL
) {
2094 struct symbol
*sym
= fn
->unop
->symbol
;
2095 if (sym
->ctype
.base_type
->type
== SYM_FN
)
2100 struct storage
*direct_stor
= new_storage(STOR_SYM
);
2101 direct_stor
->flags
|= STOR_WANTS_FREE
;
2102 direct_stor
->sym
= direct
;
2103 insn("call", direct_stor
, NULL
, NULL
);
2105 fncall
= x86_expression(fn
);
2106 emit_move(fncall
, REG_EAX
, fn
->ctype
, NULL
);
2108 strcpy(s
, "\tcall\t*%eax\n");
2109 push_text_atom(f
, s
);
2112 /* FIXME: pay attention to BITS_IN_POINTER */
2114 struct storage
*val
= new_storage(STOR_VALUE
);
2115 val
->value
= (long long) framesize
;
2116 val
->flags
= STOR_WANTS_FREE
;
2117 insn("addl", val
, REG_ESP
, NULL
);
2120 retval
= stack_alloc(4);
2121 emit_move(REG_EAX
, retval
, NULL
, "end function call");
2126 static struct storage
*x86_address_gen(struct expression
*expr
)
2128 struct function
*f
= current_func
;
2129 struct storage
*addr
;
2130 struct storage
*new;
2133 if ((expr
->type
!= EXPR_PREOP
) || (expr
->op
!= '*'))
2134 return x86_expression(expr
->address
);
2136 addr
= x86_expression(expr
->unop
);
2137 if (expr
->unop
->type
== EXPR_SYMBOL
)
2140 emit_move(addr
, REG_EAX
, NULL
, "begin deref ..");
2142 /* FIXME: operand size */
2143 strcpy(s
, "\tmovl\t(%eax), %ecx\n");
2144 push_text_atom(f
, s
);
2146 new = stack_alloc(4);
2147 emit_move(REG_ECX
, new, NULL
, ".... end deref");
2152 static struct storage
*x86_assignment(struct expression
*expr
)
2154 struct expression
*target
= expr
->left
;
2155 struct storage
*val
, *addr
;
2160 val
= x86_expression(expr
->right
);
2161 addr
= x86_address_gen(target
);
2163 switch (val
->type
) {
2164 /* copy, where both operands are memory */
2167 emit_copy(addr
, val
, expr
->ctype
);
2170 /* copy, one or zero operands are memory */
2175 emit_move(val
, addr
, expr
->left
->ctype
, NULL
);
2185 static int x86_initialization(struct symbol
*sym
, struct expression
*expr
)
2187 struct storage
*val
, *addr
;
2193 bits
= expr
->ctype
->bit_size
;
2194 val
= x86_expression(expr
);
2195 addr
= x86_symbol_expr(sym
);
2196 // FIXME! The "target" expression is for bitfield store information.
2197 // Leave it NULL, which works fine.
2198 emit_store(NULL
, addr
, val
, bits
);
2202 static struct storage
*x86_access(struct expression
*expr
)
2204 return x86_address_gen(expr
);
2207 static struct storage
*x86_preop(struct expression
*expr
)
2210 * '*' is an lvalue access, and is fundamentally different
2211 * from an arithmetic operation. Maybe it should have an
2212 * expression type of its own..
2214 if (expr
->op
== '*')
2215 return x86_access(expr
);
2216 if (expr
->op
== SPECIAL_INCREMENT
|| expr
->op
== SPECIAL_DECREMENT
)
2217 return emit_inc_dec(expr
, 0);
2218 return emit_regular_preop(expr
);
2221 static struct storage
*x86_symbol_expr(struct symbol
*sym
)
2223 struct storage
*new = stack_alloc(4);
2225 if (sym
->ctype
.modifiers
& (MOD_TOPLEVEL
| MOD_EXTERN
| MOD_STATIC
)) {
2226 printf("\tmovi.%d\t\tv%d,$%s\n", bits_in_pointer
, new->pseudo
, show_ident(sym
->ident
));
2229 if (sym
->ctype
.modifiers
& MOD_ADDRESSABLE
) {
2230 printf("\taddi.%d\t\tv%d,vFP,$%lld\n", bits_in_pointer
, new->pseudo
, sym
->value
);
2233 printf("\taddi.%d\t\tv%d,vFP,$offsetof(%s:%p)\n", bits_in_pointer
, new->pseudo
, show_ident(sym
->ident
), sym
);
2237 static void x86_symbol_init(struct symbol
*sym
)
2239 struct symbol_private
*priv
= sym
->aux
;
2240 struct expression
*expr
= sym
->initializer
;
2241 struct storage
*new;
2244 new = x86_expression(expr
);
2246 new = stack_alloc(sym
->bit_size
/ 8);
2249 priv
= calloc(1, sizeof(*priv
));
2251 /* FIXME: leak! we don't free... */
2252 /* (well, we don't free symbols either) */
2258 static int type_is_signed(struct symbol
*sym
)
2260 if (sym
->type
== SYM_NODE
)
2261 sym
= sym
->ctype
.base_type
;
2262 if (sym
->type
== SYM_PTR
)
2264 return !(sym
->ctype
.modifiers
& MOD_UNSIGNED
);
2267 static struct storage
*x86_bitfield_expr(struct expression
*expr
)
2269 return x86_access(expr
);
2272 static struct storage
*x86_label_expr(struct expression
*expr
)
2274 struct storage
*new = stack_alloc(4);
2275 printf("\tmovi.%d\t\tv%d,.L%p\n", bits_in_pointer
, new->pseudo
, expr
->label_symbol
);
2279 static struct storage
*x86_statement_expr(struct expression
*expr
)
2281 return x86_statement(expr
->statement
);
2284 static int x86_position_expr(struct expression
*expr
, struct symbol
*base
)
2286 struct storage
*new = x86_expression(expr
->init_expr
);
2287 struct symbol
*ctype
= expr
->init_sym
;
2289 printf("\tinsert v%d at [%d:%d] of %s\n", new->pseudo
,
2290 expr
->init_offset
, ctype
->bit_offset
,
2291 show_ident(base
->ident
));
2295 static void x86_initializer_expr(struct expression
*expr
, struct symbol
*ctype
)
2297 struct expression
*entry
;
2299 FOR_EACH_PTR(expr
->expr_list
, entry
) {
2300 // Nested initializers have their positions already
2301 // recursively calculated - just output them too
2302 if (entry
->type
== EXPR_INITIALIZER
) {
2303 x86_initializer_expr(entry
, ctype
);
2307 // Ignore initializer indexes and identifiers - the
2308 // evaluator has taken them into account
2309 if (entry
->type
== EXPR_IDENTIFIER
|| entry
->type
== EXPR_INDEX
)
2311 if (entry
->type
== EXPR_POS
) {
2312 x86_position_expr(entry
, ctype
);
2315 x86_initialization(ctype
, entry
);
2320 * Print out an expression. Return the pseudo that contains the
2323 static struct storage
*x86_expression(struct expression
*expr
)
2329 struct position
*pos
= &expr
->pos
;
2330 printf("\tno type at %s:%d:%d\n",
2331 input_streams
[pos
->stream
].name
,
2332 pos
->line
, pos
->pos
);
2336 switch (expr
->type
) {
2338 return x86_call_expression(expr
);
2340 case EXPR_ASSIGNMENT
:
2341 return x86_assignment(expr
);
2344 return emit_compare(expr
);
2348 return emit_binop(expr
);
2350 return x86_preop(expr
);
2352 return emit_postop(expr
);
2354 return emit_symbol_expr_init(expr
->symbol
);
2358 warn(expr
->pos
, "invalid expression after evaluation");
2361 return emit_cast_expr(expr
);
2363 return emit_value(expr
);
2365 return emit_string_expr(expr
);
2367 return x86_bitfield_expr(expr
);
2368 case EXPR_INITIALIZER
:
2369 x86_initializer_expr(expr
, expr
->ctype
);
2372 return emit_select_expr(expr
);
2373 case EXPR_CONDITIONAL
:
2374 return emit_conditional_expr(expr
);
2375 case EXPR_STATEMENT
:
2376 return x86_statement_expr(expr
);
2378 return x86_label_expr(expr
);
2380 // None of these should exist as direct expressions: they are only
2381 // valid as sub-expressions of initializers.
2383 warn(expr
->pos
, "unable to show plain initializer position expression");
2385 case EXPR_IDENTIFIER
:
2386 warn(expr
->pos
, "unable to show identifier expression");
2389 warn(expr
->pos
, "unable to show index expression");
2392 warn(expr
->pos
, "unable to show type expression");
2395 warn(expr
->pos
, "floating point support is not implemented");