2 * sparse/compile-i386.c
4 * Copyright (C) 2003 Transmeta Corp.
6 * Copyright 2003 Jeff Garzik
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29 * in general, any non-32bit SYM_BASETYPE is unlikely to work.
30 * complex initializers
32 * global struct/union variables
33 * addressing structures, and members of structures (as opposed to
34 * scalars) on the stack. Requires smarter stack frame allocation.
36 * any function argument that isn't 32 bits (or promoted to such)
56 #include "expression.h"
62 unsigned int len
; /* does NOT include terminating null */
71 struct loop_stack
*next
;
76 DECLARE_PTR_LIST(str_list
, struct atom
);
77 DECLARE_PTR_LIST(atom_list
, struct atom
);
78 DECLARE_PTR_LIST(storage_list
, struct storage
);
83 struct storage_list
*pseudo_list
;
84 struct atom_list
*atom_list
;
85 struct str_list
*str_list
;
86 struct loop_stack
*loop_stack
;
93 STOR_PSEUDO
, /* variable stored on the stack */
94 STOR_ARG
, /* function argument */
95 STOR_SYM
, /* a symbol we can directly ref in the asm */
96 STOR_REG
, /* scratch register */
97 STOR_VALUE
, /* integer constant */
98 STOR_LABEL
, /* label / jump target */
99 STOR_LABELSYM
, /* label generated from symbol's pointer value */
104 struct storage
*contains
;
105 const unsigned char aliases
[12];
106 #define own_regno aliases[0]
110 enum storage_type type
;
114 struct reg_info
*reg
;
115 struct symbol
*ctype
;
142 struct symbol
*labelsym
;
148 STOR_LABEL_VAL
= (1 << 0),
149 STOR_WANTS_FREE
= (1 << 1),
152 struct symbol_private
{
153 struct storage
*addr
;
168 unsigned int text_len
; /* w/o terminating null */
171 /* stuff for insns */
179 /* stuff for C strings */
181 struct string
*string
;
188 static struct function
*current_func
= NULL
;
189 static struct textbuf
*unit_post_text
= NULL
;
190 static const char *current_section
;
192 static void emit_comment(const char * fmt
, ...) FORMAT_ATTR(1);
193 static void emit_move(struct storage
*src
, struct storage
*dest
,
194 struct symbol
*ctype
, const char *comment
);
195 static struct storage
*x86_address_gen(struct expression
*expr
);
196 static struct storage
*x86_symbol_expr(struct symbol
*sym
);
197 static void x86_symbol(struct symbol
*sym
);
198 static struct storage
*x86_statement(struct statement
*stmt
);
199 static struct storage
*x86_expression(struct expression
*expr
);
203 AL
, DL
, CL
, BL
, AH
, DH
, CH
, BH
, // 8-bit
204 AX
, DX
, CX
, BX
, SI
, DI
, BP
, SP
, // 16-bit
205 EAX
, EDX
, ECX
, EBX
, ESI
, EDI
, EBP
, ESP
, // 32-bit
206 EAX_EDX
, ECX_EBX
, ESI_EDI
, // 64-bit
209 /* This works on regno's, reg_info's and hardreg_storage's */
210 #define byte_reg(reg) ((reg) - 16)
211 #define highbyte_reg(reg) ((reg)-12)
212 #define word_reg(reg) ((reg)-8)
214 #define REGINFO(nr, str, conflicts...) [nr] = { .name = str, .aliases = { nr , conflicts } }
216 static struct reg_info reg_info_table
[] = {
217 REGINFO( AL
, "%al", AX
, EAX
, EAX_EDX
),
218 REGINFO( DL
, "%dl", DX
, EDX
, EAX_EDX
),
219 REGINFO( CL
, "%cl", CX
, ECX
, ECX_EBX
),
220 REGINFO( BL
, "%bl", BX
, EBX
, ECX_EBX
),
221 REGINFO( AH
, "%ah", AX
, EAX
, EAX_EDX
),
222 REGINFO( DH
, "%dh", DX
, EDX
, EAX_EDX
),
223 REGINFO( CH
, "%ch", CX
, ECX
, ECX_EBX
),
224 REGINFO( BH
, "%bh", BX
, EBX
, ECX_EBX
),
225 REGINFO( AX
, "%ax", AL
, AH
, EAX
, EAX_EDX
),
226 REGINFO( DX
, "%dx", DL
, DH
, EDX
, EAX_EDX
),
227 REGINFO( CX
, "%cx", CL
, CH
, ECX
, ECX_EBX
),
228 REGINFO( BX
, "%bx", BL
, BH
, EBX
, ECX_EBX
),
229 REGINFO( SI
, "%si", ESI
, ESI_EDI
),
230 REGINFO( DI
, "%di", EDI
, ESI_EDI
),
231 REGINFO( BP
, "%bp", EBP
),
232 REGINFO( SP
, "%sp", ESP
),
233 REGINFO(EAX
, "%eax", AL
, AH
, AX
, EAX_EDX
),
234 REGINFO(EDX
, "%edx", DL
, DH
, DX
, EAX_EDX
),
235 REGINFO(ECX
, "%ecx", CL
, CH
, CX
, ECX_EBX
),
236 REGINFO(EBX
, "%ebx", BL
, BH
, BX
, ECX_EBX
),
237 REGINFO(ESI
, "%esi", SI
, ESI_EDI
),
238 REGINFO(EDI
, "%edi", DI
, ESI_EDI
),
239 REGINFO(EBP
, "%ebp", BP
),
240 REGINFO(ESP
, "%esp", SP
),
241 REGINFO(EAX_EDX
, "%eax:%edx", AL
, AH
, AX
, EAX
, DL
, DH
, DX
, EDX
),
242 REGINFO(ECX_EBX
, "%ecx:%ebx", CL
, CH
, CX
, ECX
, BL
, BH
, BX
, EBX
),
243 REGINFO(ESI_EDI
, "%esi:%edi", SI
, ESI
, DI
, EDI
),
246 #define REGSTORAGE(nr) [nr] = { .type = STOR_REG, .reg = reg_info_table + (nr) }
248 static struct storage hardreg_storage_table
[] = {
249 REGSTORAGE(AL
), REGSTORAGE(DL
), REGSTORAGE(CL
), REGSTORAGE(BL
),
250 REGSTORAGE(AH
), REGSTORAGE(DH
), REGSTORAGE(CH
), REGSTORAGE(BH
),
251 REGSTORAGE(AX
), REGSTORAGE(DX
), REGSTORAGE(CX
), REGSTORAGE(BX
),
252 REGSTORAGE(SI
), REGSTORAGE(DI
), REGSTORAGE(BP
), REGSTORAGE(SP
),
253 REGSTORAGE(EAX
), REGSTORAGE(EDX
), REGSTORAGE(ECX
), REGSTORAGE(EBX
),
254 REGSTORAGE(ESI
), REGSTORAGE(EDI
), REGSTORAGE(EBP
), REGSTORAGE(ESP
),
255 REGSTORAGE(EAX_EDX
), REGSTORAGE(ECX_EBX
), REGSTORAGE(ESI_EDI
),
258 #define REG_EAX (&hardreg_storage_table[EAX])
259 #define REG_ECX (&hardreg_storage_table[ECX])
260 #define REG_EDX (&hardreg_storage_table[EDX])
261 #define REG_ESP (&hardreg_storage_table[ESP])
262 #define REG_DL (&hardreg_storage_table[DL])
263 #define REG_DX (&hardreg_storage_table[DX])
264 #define REG_AL (&hardreg_storage_table[AL])
265 #define REG_AX (&hardreg_storage_table[AX])
267 static DECLARE_BITMAP(regs_in_use
, 256);
269 static inline struct storage
* reginfo_reg(struct reg_info
*info
)
271 return hardreg_storage_table
+ info
->own_regno
;
274 static struct storage
* get_hardreg(struct storage
*reg
, int clear
)
276 struct reg_info
*info
= reg
->reg
;
277 const unsigned char *aliases
;
280 aliases
= info
->aliases
;
281 while ((regno
= *aliases
++) != NOREG
) {
282 if (test_bit(regno
, regs_in_use
))
285 reg_info_table
[regno
].contains
= NULL
;
287 set_bit(info
->own_regno
, regs_in_use
);
290 fprintf(stderr
, "register %s is busy\n", info
->name
);
291 if (regno
+ reg_info_table
!= info
)
292 fprintf(stderr
, " conflicts with %s\n", reg_info_table
[regno
].name
);
296 static void put_reg(struct storage
*reg
)
298 struct reg_info
*info
= reg
->reg
;
299 int regno
= info
->own_regno
;
301 if (test_and_clear_bit(regno
, regs_in_use
))
303 fprintf(stderr
, "freeing already free'd register %s\n", reg_info_table
[regno
].name
);
308 const unsigned char regs
[30];
311 static struct regclass regclass_8
= { "8-bit", { AL
, DL
, CL
, BL
, AH
, DH
, CH
, BH
}};
312 static struct regclass regclass_16
= { "16-bit", { AX
, DX
, CX
, BX
, SI
, DI
, BP
}};
313 static struct regclass regclass_32
= { "32-bit", { EAX
, EDX
, ECX
, EBX
, ESI
, EDI
, EBP
}};
314 static struct regclass regclass_64
= { "64-bit", { EAX_EDX
, ECX_EBX
, ESI_EDI
}};
316 static struct regclass regclass_32_8
= { "32-bit bytes", { EAX
, EDX
, ECX
, EBX
}};
318 static struct regclass
*get_regclass_bits(int bits
)
321 case 8: return ®class_8
;
322 case 16: return ®class_16
;
323 case 64: return ®class_64
;
324 default: return ®class_32
;
328 static struct regclass
*get_regclass(struct expression
*expr
)
330 return get_regclass_bits(expr
->ctype
->bit_size
);
333 static int register_busy(int regno
)
335 if (!test_bit(regno
, regs_in_use
)) {
336 struct reg_info
*info
= reg_info_table
+ regno
;
337 const unsigned char *regs
= info
->aliases
+1;
339 while ((regno
= *regs
) != NOREG
) {
341 if (test_bit(regno
, regs_in_use
))
350 static struct storage
*get_reg(struct regclass
*class)
352 const unsigned char *regs
= class->regs
;
355 while ((regno
= *regs
) != NOREG
) {
357 if (register_busy(regno
))
359 return get_hardreg(hardreg_storage_table
+ regno
, 1);
361 fprintf(stderr
, "Ran out of %s registers\n", class->name
);
365 static struct storage
*get_reg_value(struct storage
*value
, struct regclass
*class)
367 struct reg_info
*info
;
370 /* Do we already have it somewhere */
372 if (info
&& info
->contains
== value
) {
373 emit_comment("already have register %s", info
->name
);
374 return get_hardreg(hardreg_storage_table
+ info
->own_regno
, 0);
377 reg
= get_reg(class);
378 emit_move(value
, reg
, value
->ctype
, "reload register");
380 info
->contains
= value
;
385 static struct storage
*temp_from_bits(unsigned int bit_size
)
387 return get_reg(get_regclass_bits(bit_size
));
390 static inline unsigned int pseudo_offset(struct storage
*s
)
392 if (s
->type
!= STOR_PSEUDO
)
393 return 123456; /* intentionally bogus value */
398 static inline unsigned int arg_offset(struct storage
*s
)
400 if (s
->type
!= STOR_ARG
)
401 return 123456; /* intentionally bogus value */
403 /* FIXME: this is wrong wrong wrong */
404 return current_func
->stack_size
+ ((1 + s
->idx
) * 4);
407 static const char *pretty_offset(int ofs
)
409 static char esp_buf
[64];
412 sprintf(esp_buf
, "%d(%%esp)", ofs
);
414 strcpy(esp_buf
, "(%esp)");
419 static void stor_sym_init(struct symbol
*sym
)
421 struct storage
*stor
;
422 struct symbol_private
*priv
;
424 priv
= calloc(1, sizeof(*priv
) + sizeof(*stor
));
426 die("OOM in stor_sym_init");
428 stor
= (struct storage
*) (priv
+ 1);
431 stor
->type
= STOR_SYM
;
435 static const char *stor_op_name(struct storage
*s
)
437 static char name
[32];
441 strcpy(name
, pretty_offset((int) pseudo_offset(s
)));
444 strcpy(name
, pretty_offset((int) arg_offset(s
)));
447 strcpy(name
, show_ident(s
->sym
->ident
));
450 strcpy(name
, s
->reg
->name
);
453 sprintf(name
, "$%lld", s
->value
);
456 sprintf(name
, "%s.L%d", s
->flags
& STOR_LABEL_VAL
? "$" : "",
460 sprintf(name
, "%s.LS%p", s
->flags
& STOR_LABEL_VAL
? "$" : "",
468 static struct atom
*new_atom(enum atom_type type
)
472 atom
= calloc(1, sizeof(*atom
)); /* TODO: chunked alloc */
481 static inline void push_cstring(struct function
*f
, struct string
*str
,
486 atom
= new_atom(ATOM_CSTR
);
490 add_ptr_list(&f
->str_list
, atom
); /* note: _not_ atom_list */
493 static inline void push_atom(struct function
*f
, struct atom
*atom
)
495 add_ptr_list(&f
->atom_list
, atom
);
498 static void push_text_atom(struct function
*f
, const char *text
)
500 struct atom
*atom
= new_atom(ATOM_TEXT
);
502 atom
->text
= strdup(text
);
503 atom
->text_len
= strlen(text
);
508 static struct storage
*new_storage(enum storage_type type
)
510 struct storage
*stor
;
512 stor
= calloc(1, sizeof(*stor
));
514 die("OOM in new_storage");
521 static struct storage
*stack_alloc(int n_bytes
)
523 struct function
*f
= current_func
;
524 struct storage
*stor
;
528 stor
= new_storage(STOR_PSEUDO
);
529 stor
->type
= STOR_PSEUDO
;
530 stor
->pseudo
= f
->pseudo_nr
;
531 stor
->offset
= f
->stack_size
; /* FIXME: stack req. natural align */
532 stor
->size
= n_bytes
;
533 f
->stack_size
+= n_bytes
;
536 add_ptr_list(&f
->pseudo_list
, stor
);
541 static struct storage
*new_labelsym(struct symbol
*sym
)
543 struct storage
*stor
;
545 stor
= new_storage(STOR_LABELSYM
);
548 stor
->flags
|= STOR_WANTS_FREE
;
549 stor
->labelsym
= sym
;
555 static struct storage
*new_val(long long value
)
557 struct storage
*stor
;
559 stor
= new_storage(STOR_VALUE
);
562 stor
->flags
|= STOR_WANTS_FREE
;
569 static int new_label(void)
571 static int label
= 0;
575 static void textbuf_push(struct textbuf
**buf_p
, const char *text
)
577 struct textbuf
*tmp
, *list
= *buf_p
;
578 unsigned int text_len
= strlen(text
);
579 unsigned int alloc_len
= text_len
+ 1 + sizeof(*list
);
581 tmp
= calloc(1, alloc_len
);
583 die("OOM on textbuf alloc");
585 tmp
->text
= ((void *) tmp
) + sizeof(*tmp
);
586 memcpy(tmp
->text
, text
, text_len
+ 1);
589 /* add to end of list */
594 tmp
->prev
= list
->prev
;
595 tmp
->prev
->next
= tmp
;
603 static void textbuf_emit(struct textbuf
**buf_p
)
605 struct textbuf
*tmp
, *list
= *buf_p
;
609 if (tmp
->next
== tmp
)
612 tmp
->prev
->next
= tmp
->next
;
613 tmp
->next
->prev
= tmp
->prev
;
617 fputs(tmp
->text
, stdout
);
625 static void insn(const char *insn
, struct storage
*op1
, struct storage
*op2
,
626 const char *comment_in
)
628 struct function
*f
= current_func
;
629 struct atom
*atom
= new_atom(ATOM_INSN
);
631 assert(insn
!= NULL
);
633 strcpy(atom
->insn
, insn
);
634 if (comment_in
&& (*comment_in
))
635 strncpy(atom
->comment
, comment_in
,
636 sizeof(atom
->comment
) - 1);
644 static void emit_comment(const char *fmt
, ...)
646 struct function
*f
= current_func
;
647 static char tmpbuf
[100] = "\t# ";
652 i
= vsnprintf(tmpbuf
+3, sizeof(tmpbuf
)-4, fmt
, args
);
656 push_text_atom(f
, tmpbuf
);
659 static void emit_label (int label
, const char *comment
)
661 struct function
*f
= current_func
;
665 sprintf(s
, ".L%d:\n", label
);
667 sprintf(s
, ".L%d:\t\t\t\t\t# %s\n", label
, comment
);
669 push_text_atom(f
, s
);
672 static void emit_labelsym (struct symbol
*sym
, const char *comment
)
674 struct function
*f
= current_func
;
678 sprintf(s
, ".LS%p:\n", sym
);
680 sprintf(s
, ".LS%p:\t\t\t\t# %s\n", sym
, comment
);
682 push_text_atom(f
, s
);
685 void emit_unit_begin(const char *basename
)
687 printf("\t.file\t\"%s\"\n", basename
);
690 void emit_unit_end(void)
692 textbuf_emit(&unit_post_text
);
693 printf("\t.ident\t\"sparse silly x86 backend (version %s)\"\n", sparse_version
);
696 /* conditionally switch sections */
697 static void emit_section(const char *s
)
699 if (s
== current_section
)
701 if (current_section
&& (!strcmp(s
, current_section
)))
708 static void emit_insn_atom(struct function
*f
, struct atom
*atom
)
712 struct storage
*op1
= atom
->op1
;
713 struct storage
*op2
= atom
->op2
;
715 if (atom
->comment
[0])
716 sprintf(comment
, "\t\t# %s", atom
->comment
);
722 strcpy(tmp
, stor_op_name(op1
));
723 sprintf(s
, "\t%s\t%s, %s%s\n",
724 atom
->insn
, tmp
, stor_op_name(op2
), comment
);
725 } else if (atom
->op1
)
726 sprintf(s
, "\t%s\t%s%s%s\n",
727 atom
->insn
, stor_op_name(op1
),
728 comment
[0] ? "\t" : "", comment
);
730 sprintf(s
, "\t%s\t%s%s\n",
732 comment
[0] ? "\t\t" : "", comment
);
734 if (write(STDOUT_FILENO
, s
, strlen(s
)) < 0)
735 die("can't write to stdout");
738 static void emit_atom_list(struct function
*f
)
742 FOR_EACH_PTR(f
->atom_list
, atom
) {
743 switch (atom
->type
) {
745 if (write(STDOUT_FILENO
, atom
->text
, atom
->text_len
) < 0)
746 die("can't write to stdout");
750 emit_insn_atom(f
, atom
);
756 } END_FOR_EACH_PTR(atom
);
759 static void emit_string_list(struct function
*f
)
763 emit_section(".section\t.rodata");
765 FOR_EACH_PTR(f
->str_list
, atom
) {
766 /* FIXME: escape " in string */
767 printf(".L%d:\n", atom
->label
);
768 printf("\t.string\t%s\n", show_string(atom
->string
));
771 } END_FOR_EACH_PTR(atom
);
774 static void func_cleanup(struct function
*f
)
776 struct storage
*stor
;
779 FOR_EACH_PTR(f
->atom_list
, atom
) {
780 if ((atom
->type
== ATOM_TEXT
) && (atom
->text
))
782 if (atom
->op1
&& (atom
->op1
->flags
& STOR_WANTS_FREE
))
784 if (atom
->op2
&& (atom
->op2
->flags
& STOR_WANTS_FREE
))
787 } END_FOR_EACH_PTR(atom
);
789 FOR_EACH_PTR(f
->pseudo_list
, stor
) {
791 } END_FOR_EACH_PTR(stor
);
793 free_ptr_list(&f
->pseudo_list
);
797 /* function prologue */
798 static void emit_func_pre(struct symbol
*sym
)
802 unsigned int i
, argc
= 0, alloc_len
;
804 struct symbol_private
*privbase
;
805 struct storage
*storage_base
;
806 struct symbol
*base_type
= sym
->ctype
.base_type
;
808 FOR_EACH_PTR(base_type
->arguments
, arg
) {
810 } END_FOR_EACH_PTR(arg
);
814 (argc
* sizeof(struct symbol
*)) +
815 (argc
* sizeof(struct symbol_private
)) +
816 (argc
* sizeof(struct storage
));
817 mem
= calloc(1, alloc_len
);
819 die("OOM on func info");
821 f
= (struct function
*) mem
;
823 f
->argv
= (struct symbol
**) mem
;
824 mem
+= (argc
* sizeof(struct symbol
*));
825 privbase
= (struct symbol_private
*) mem
;
826 mem
+= (argc
* sizeof(struct symbol_private
));
827 storage_base
= (struct storage
*) mem
;
830 f
->ret_target
= new_label();
833 FOR_EACH_PTR(base_type
->arguments
, arg
) {
835 arg
->aux
= &privbase
[i
];
836 storage_base
[i
].type
= STOR_ARG
;
837 storage_base
[i
].idx
= i
;
838 privbase
[i
].addr
= &storage_base
[i
];
840 } END_FOR_EACH_PTR(arg
);
842 assert(current_func
== NULL
);
846 /* function epilogue */
847 static void emit_func_post(struct symbol
*sym
)
849 const char *name
= show_ident(sym
->ident
);
850 struct function
*f
= current_func
;
851 int stack_size
= f
->stack_size
;
856 /* function prologue */
857 emit_section(".text");
858 if ((sym
->ctype
.modifiers
& MOD_STATIC
) == 0)
859 printf(".globl %s\n", name
);
860 printf("\t.type\t%s, @function\n", name
);
861 printf("%s:\n", name
);
864 char pseudo_const
[16];
866 sprintf(pseudo_const
, "$%d", stack_size
);
867 printf("\tsubl\t%s, %%esp\n", pseudo_const
);
870 /* function epilogue */
872 /* jump target for 'return' statements */
873 emit_label(f
->ret_target
, NULL
);
878 val
= new_storage(STOR_VALUE
);
879 val
->value
= (long long) (stack_size
);
880 val
->flags
= STOR_WANTS_FREE
;
882 insn("addl", val
, REG_ESP
, NULL
);
885 insn("ret", NULL
, NULL
, NULL
);
887 /* output everything to stdout */
888 fflush(stdout
); /* paranoia; needed? */
891 /* function footer */
892 name
= show_ident(sym
->ident
);
893 printf("\t.size\t%s, .-%s\n", name
, name
);
899 /* emit object (a.k.a. variable, a.k.a. data) prologue */
900 static void emit_object_pre(const char *name
, unsigned long modifiers
,
901 unsigned long alignment
, unsigned int byte_size
)
903 if ((modifiers
& MOD_STATIC
) == 0)
904 printf(".globl %s\n", name
);
905 emit_section(".data");
907 printf("\t.align %lu\n", alignment
);
908 printf("\t.type\t%s, @object\n", name
);
909 printf("\t.size\t%s, %d\n", name
, byte_size
);
910 printf("%s:\n", name
);
913 /* emit value (only) for an initializer scalar */
914 static void emit_scalar(struct expression
*expr
, unsigned int bit_size
)
919 assert(expr
->type
== EXPR_VALUE
);
921 if (expr
->value
== 0ULL) {
922 printf("\t.zero\t%d\n", bit_size
/ 8);
926 ll
= (long long) expr
->value
;
929 case 8: type
= "byte"; ll
= (char) ll
; break;
930 case 16: type
= "value"; ll
= (short) ll
; break;
931 case 32: type
= "long"; ll
= (int) ll
; break;
932 case 64: type
= "quad"; break;
933 default: type
= NULL
; break;
936 assert(type
!= NULL
);
938 printf("\t.%s\t%lld\n", type
, ll
);
941 static void emit_global_noinit(const char *name
, unsigned long modifiers
,
942 unsigned long alignment
, unsigned int byte_size
)
946 if (modifiers
& MOD_STATIC
) {
947 sprintf(s
, "\t.local\t%s\n", name
);
948 textbuf_push(&unit_post_text
, s
);
951 sprintf(s
, "\t.comm\t%s,%d,%lu\n", name
, byte_size
, alignment
);
953 sprintf(s
, "\t.comm\t%s,%d\n", name
, byte_size
);
954 textbuf_push(&unit_post_text
, s
);
957 static int ea_current
, ea_last
;
959 static void emit_initializer(struct symbol
*sym
,
960 struct expression
*expr
)
962 int distance
= ea_current
- ea_last
- 1;
965 printf("\t.zero\t%d\n", (sym
->bit_size
/ 8) * distance
);
967 if (expr
->type
== EXPR_VALUE
) {
968 struct symbol
*base_type
= sym
->ctype
.base_type
;
969 assert(base_type
!= NULL
);
971 emit_scalar(expr
, sym
->bit_size
/ get_expression_value(base_type
->array_size
));
974 if (expr
->type
!= EXPR_INITIALIZER
)
977 assert(0); /* FIXME */
980 static int sort_array_cmp(const struct expression
*a
,
981 const struct expression
*b
)
983 int a_ofs
= 0, b_ofs
= 0;
985 if (a
->type
== EXPR_POS
)
986 a_ofs
= (int) a
->init_offset
;
987 if (b
->type
== EXPR_POS
)
988 b_ofs
= (int) b
->init_offset
;
990 return a_ofs
- b_ofs
;
993 /* move to front-end? */
994 static void sort_array(struct expression
*expr
)
996 struct expression
*entry
, **list
;
997 unsigned int elem
, sorted
, i
;
999 elem
= expression_list_size(expr
->expr_list
);
1003 list
= malloc(sizeof(entry
) * elem
);
1005 die("OOM in sort_array");
1007 /* this code is no doubt evil and ignores EXPR_INDEX possibly
1008 * to its detriment and other nasty things. improvements
1013 FOR_EACH_PTR(expr
->expr_list
, entry
) {
1014 if ((entry
->type
== EXPR_POS
) || (entry
->type
== EXPR_VALUE
)) {
1015 /* add entry to list[], in sorted order */
1020 for (i
= 0; i
< sorted
; i
++)
1021 if (sort_array_cmp(entry
, list
[i
]) <= 0)
1024 /* If inserting into the middle of list[]
1025 * instead of appending, we memmove.
1026 * This is ugly, but thankfully
1027 * uncommon. Input data with tons of
1028 * entries very rarely have explicit
1029 * offsets. convert to qsort eventually...
1032 memmove(&list
[i
+ 1], &list
[i
],
1033 (sorted
- i
) * sizeof(entry
));
1038 } END_FOR_EACH_PTR(entry
);
1041 FOR_EACH_PTR(expr
->expr_list
, entry
) {
1042 if ((entry
->type
== EXPR_POS
) || (entry
->type
== EXPR_VALUE
))
1043 *THIS_ADDRESS(entry
) = list
[i
++];
1044 } END_FOR_EACH_PTR(entry
);
1049 static void emit_array(struct symbol
*sym
)
1051 struct symbol
*base_type
= sym
->ctype
.base_type
;
1052 struct expression
*expr
= sym
->initializer
;
1053 struct expression
*entry
;
1055 assert(base_type
!= NULL
);
1061 emit_object_pre(show_ident(sym
->ident
), sym
->ctype
.modifiers
,
1062 sym
->ctype
.alignment
,
1067 FOR_EACH_PTR(expr
->expr_list
, entry
) {
1068 if (entry
->type
== EXPR_VALUE
) {
1070 emit_initializer(sym
, entry
);
1071 ea_last
= ea_current
;
1072 } else if (entry
->type
== EXPR_POS
) {
1074 entry
->init_offset
/ (base_type
->bit_size
/ 8);
1075 emit_initializer(sym
, entry
->init_expr
);
1076 ea_last
= ea_current
;
1078 } END_FOR_EACH_PTR(entry
);
1081 void emit_one_symbol(struct symbol
*sym
)
1086 static void emit_copy(struct storage
*dest
, struct storage
*src
,
1087 struct symbol
*ctype
)
1089 struct storage
*reg
= NULL
;
1090 unsigned int bit_size
;
1092 /* FIXME: Bitfield copy! */
1094 bit_size
= src
->size
* 8;
1097 if ((src
->type
== STOR_ARG
) && (bit_size
< 32))
1100 reg
= temp_from_bits(bit_size
);
1101 emit_move(src
, reg
, ctype
, "begin copy ..");
1103 bit_size
= dest
->size
* 8;
1106 if ((dest
->type
== STOR_ARG
) && (bit_size
< 32))
1109 emit_move(reg
, dest
, ctype
, ".... end copy");
1113 static void emit_store(struct expression
*dest_expr
, struct storage
*dest
,
1114 struct storage
*src
, int bits
)
1116 /* FIXME: Bitfield store! */
1117 printf("\tst.%d\t\tv%d,[v%d]\n", bits
, src
->pseudo
, dest
->pseudo
);
1120 static void emit_scalar_noinit(struct symbol
*sym
)
1122 emit_global_noinit(show_ident(sym
->ident
),
1123 sym
->ctype
.modifiers
, sym
->ctype
.alignment
,
1128 static void emit_array_noinit(struct symbol
*sym
)
1130 emit_global_noinit(show_ident(sym
->ident
),
1131 sym
->ctype
.modifiers
, sym
->ctype
.alignment
,
1132 get_expression_value(sym
->array_size
) * (sym
->bit_size
/ 8));
1136 static const char *opbits(const char *insn
, unsigned int bits
)
1138 static char opbits_str
[32];
1142 case 8: c
= 'b'; break;
1143 case 16: c
= 'w'; break;
1144 case 32: c
= 'l'; break;
1145 case 64: c
= 'q'; break;
1146 default: abort(); break;
1149 sprintf(opbits_str
, "%s%c", insn
, c
);
1154 static void emit_move(struct storage
*src
, struct storage
*dest
,
1155 struct symbol
*ctype
, const char *comment
)
1158 unsigned int is_signed
;
1159 unsigned int is_dest
= (src
->type
== STOR_REG
);
1163 bits
= ctype
->bit_size
;
1164 is_signed
= is_signed_type(ctype
);
1171 * Are we moving from a register to a register?
1172 * Make the new reg to be the "cache".
1174 if ((dest
->type
== STOR_REG
) && (src
->type
== STOR_REG
)) {
1175 struct storage
*backing
;
1181 backing
= src
->reg
->contains
;
1183 /* Is it still valid? */
1184 if (backing
->reg
!= src
->reg
)
1187 backing
->reg
= dest
->reg
;
1189 dest
->reg
->contains
= backing
;
1190 insn("mov", src
, dest
, NULL
);
1195 * Are we moving to a register from a non-reg?
1197 * See if we have the non-reg source already cached
1200 if (dest
->type
== STOR_REG
) {
1202 struct reg_info
*info
= src
->reg
;
1203 if (info
->contains
== src
) {
1204 src
= reginfo_reg(info
);
1208 dest
->reg
->contains
= src
;
1209 src
->reg
= dest
->reg
;
1212 if (src
->type
== STOR_REG
) {
1213 /* We could just mark the register dirty here and do lazy store.. */
1214 src
->reg
->contains
= dest
;
1215 dest
->reg
= src
->reg
;
1218 if ((bits
== 8) || (bits
== 16)) {
1222 opname
= is_signed
? "movsx" : "movzx";
1226 insn(opbits(opname
, bits
), src
, dest
, comment
);
1229 static struct storage
*emit_compare(struct expression
*expr
)
1231 struct storage
*left
= x86_expression(expr
->left
);
1232 struct storage
*right
= x86_expression(expr
->right
);
1233 struct storage
*reg1
, *reg2
;
1234 struct storage
*new, *val
;
1235 const char *opname
= NULL
;
1236 unsigned int right_bits
= expr
->right
->ctype
->bit_size
;
1239 case '<': opname
= "setl"; break;
1240 case '>': opname
= "setg"; break;
1242 opname
= "setle"; break;
1244 opname
= "setge"; break;
1245 case SPECIAL_EQUAL
: opname
= "sete"; break;
1246 case SPECIAL_NOTEQUAL
: opname
= "setne"; break;
1247 case SPECIAL_UNSIGNED_LT
:
1248 opname
= "setb"; break;
1249 case SPECIAL_UNSIGNED_GT
:
1250 opname
= "seta"; break;
1251 case SPECIAL_UNSIGNED_LTE
:
1252 opname
= "setb"; break;
1253 case SPECIAL_UNSIGNED_GTE
:
1254 opname
= "setae"; break;
1261 val
= new_storage(STOR_VALUE
);
1262 val
->flags
= STOR_WANTS_FREE
;
1264 reg1
= get_reg(®class_32_8
);
1265 emit_move(val
, reg1
, NULL
, NULL
);
1267 /* move op1 into EAX */
1268 reg2
= get_reg_value(left
, get_regclass(expr
->left
));
1270 /* perform comparison, RHS (op1, right) and LHS (op2, EAX) */
1271 insn(opbits("cmp", right_bits
), right
, reg2
, NULL
);
1274 /* store result of operation, 0 or 1, in DL using SETcc */
1275 insn(opname
, byte_reg(reg1
), NULL
, NULL
);
1277 /* finally, store the result (DL) in a new pseudo / stack slot */
1278 new = stack_alloc(4);
1279 emit_move(reg1
, new, NULL
, "end EXPR_COMPARE");
1285 static struct storage
*emit_value(struct expression
*expr
)
1287 #if 0 /* old and slow way */
1288 struct storage
*new = stack_alloc(4);
1289 struct storage
*val
;
1291 val
= new_storage(STOR_VALUE
);
1292 val
->value
= (long long) expr
->value
;
1293 val
->flags
= STOR_WANTS_FREE
;
1294 insn("movl", val
, new, NULL
);
1298 struct storage
*val
;
1300 val
= new_storage(STOR_VALUE
);
1301 val
->value
= (long long) expr
->value
;
1303 return val
; /* FIXME: memory leak */
1307 static struct storage
*emit_divide(struct expression
*expr
, struct storage
*left
, struct storage
*right
)
1309 struct storage
*eax_edx
;
1310 struct storage
*reg
, *new;
1311 struct storage
*val
= new_storage(STOR_VALUE
);
1313 emit_comment("begin DIVIDE");
1314 eax_edx
= get_hardreg(hardreg_storage_table
+ EAX_EDX
, 1);
1317 val
->flags
= STOR_WANTS_FREE
;
1318 emit_move(val
, REG_EDX
, NULL
, NULL
);
1320 new = stack_alloc(expr
->ctype
->bit_size
/ 8);
1322 /* EAX is dividend */
1323 emit_move(left
, REG_EAX
, NULL
, NULL
);
1325 reg
= get_reg_value(right
, ®class_32
);
1328 insn("div", reg
, REG_EAX
, NULL
);
1332 if (expr
->op
== '%')
1334 emit_move(reg
, new, NULL
, NULL
);
1337 emit_comment("end DIVIDE");
1341 static struct storage
*emit_binop(struct expression
*expr
)
1343 struct storage
*left
= x86_expression(expr
->left
);
1344 struct storage
*right
= x86_expression(expr
->right
);
1345 struct storage
*new;
1346 struct storage
*dest
, *src
;
1347 const char *opname
= NULL
;
1348 const char *suffix
= NULL
;
1352 /* Divides have special register constraints */
1353 if ((expr
->op
== '/') || (expr
->op
== '%'))
1354 return emit_divide(expr
, left
, right
);
1356 is_signed
= is_signed_type(expr
->ctype
);
1374 case SPECIAL_LEFTSHIFT
:
1377 case SPECIAL_RIGHTSHIFT
:
1389 case SPECIAL_LOGICAL_AND
:
1390 warning(expr
->pos
, "bogus bitwise and for logical op (should use '2*setne + and' or something)");
1393 case SPECIAL_LOGICAL_OR
:
1394 warning(expr
->pos
, "bogus bitwise or for logical op (should use 'or + setne' or something)");
1398 error_die(expr
->pos
, "unhandled binop '%s'\n", show_special(expr
->op
));
1402 dest
= get_reg_value(right
, ®class_32
);
1403 src
= get_reg_value(left
, ®class_32
);
1404 switch (expr
->ctype
->bit_size
) {
1415 suffix
= "q"; /* FIXME */
1422 snprintf(opstr
, sizeof(opstr
), "%s%s", opname
, suffix
);
1425 insn(opstr
, src
, dest
, NULL
);
1428 /* store result in new pseudo / stack slot */
1429 new = stack_alloc(expr
->ctype
->bit_size
/ 8);
1430 emit_move(dest
, new, NULL
, "end EXPR_BINOP");
1437 static int emit_conditional_test(struct storage
*val
)
1439 struct storage
*reg
;
1440 struct storage
*target_val
;
1443 /* load result into EAX */
1444 emit_comment("begin if/conditional");
1445 reg
= get_reg_value(val
, ®class_32
);
1447 /* compare result with zero */
1448 insn("test", reg
, reg
, NULL
);
1451 /* create conditional-failed label to jump to */
1452 target_false
= new_label();
1453 target_val
= new_storage(STOR_LABEL
);
1454 target_val
->label
= target_false
;
1455 target_val
->flags
= STOR_WANTS_FREE
;
1456 insn("jz", target_val
, NULL
, NULL
);
1458 return target_false
;
1461 static int emit_conditional_end(int target_false
)
1463 struct storage
*cond_end_st
;
1466 /* finished generating code for if-true statement.
1467 * add a jump-to-end jump to avoid falling through
1468 * to the if-false statement code.
1470 cond_end
= new_label();
1471 cond_end_st
= new_storage(STOR_LABEL
);
1472 cond_end_st
->label
= cond_end
;
1473 cond_end_st
->flags
= STOR_WANTS_FREE
;
1474 insn("jmp", cond_end_st
, NULL
, NULL
);
1476 /* if we have both if-true and if-false statements,
1477 * the failed-conditional case will fall through to here
1479 emit_label(target_false
, NULL
);
1484 static void emit_if_conditional(struct statement
*stmt
)
1486 struct storage
*val
;
1489 /* emit test portion of conditional */
1490 val
= x86_expression(stmt
->if_conditional
);
1491 cond_end
= emit_conditional_test(val
);
1493 /* emit if-true statement */
1494 x86_statement(stmt
->if_true
);
1496 /* emit if-false statement, if present */
1497 if (stmt
->if_false
) {
1498 cond_end
= emit_conditional_end(cond_end
);
1499 x86_statement(stmt
->if_false
);
1502 /* end of conditional; jump target for if-true branch */
1503 emit_label(cond_end
, "end if");
1506 static struct storage
*emit_inc_dec(struct expression
*expr
, int postop
)
1508 struct storage
*addr
= x86_address_gen(expr
->unop
);
1509 struct storage
*retval
;
1512 strcpy(opname
, opbits(expr
->op
== SPECIAL_INCREMENT
? "inc" : "dec",
1513 expr
->ctype
->bit_size
));
1516 struct storage
*new = stack_alloc(4);
1518 emit_copy(new, addr
, expr
->unop
->ctype
);
1524 insn(opname
, addr
, NULL
, NULL
);
1529 static struct storage
*emit_postop(struct expression
*expr
)
1531 return emit_inc_dec(expr
, 1);
1534 static struct storage
*emit_return_stmt(struct statement
*stmt
)
1536 struct function
*f
= current_func
;
1537 struct expression
*expr
= stmt
->ret_value
;
1538 struct storage
*val
= NULL
, *jmplbl
;
1540 if (expr
&& expr
->ctype
) {
1541 val
= x86_expression(expr
);
1542 assert(val
!= NULL
);
1543 emit_move(val
, REG_EAX
, expr
->ctype
, "return");
1546 jmplbl
= new_storage(STOR_LABEL
);
1547 jmplbl
->flags
|= STOR_WANTS_FREE
;
1548 jmplbl
->label
= f
->ret_target
;
1549 insn("jmp", jmplbl
, NULL
, NULL
);
1554 static struct storage
*emit_conditional_expr(struct expression
*expr
)
1556 struct storage
*cond
, *stot
= NULL
, *stof
= NULL
;
1557 struct storage
*new = stack_alloc(expr
->ctype
->bit_size
/ 8);
1558 int target_false
, cond_end
;
1560 /* evaluate conditional */
1561 cond
= x86_expression(expr
->conditional
);
1562 target_false
= emit_conditional_test(cond
);
1564 /* handle if-true part of the expression */
1565 stot
= x86_expression(expr
->cond_true
);
1567 emit_copy(new, stot
, expr
->ctype
);
1569 cond_end
= emit_conditional_end(target_false
);
1571 /* handle if-false part of the expression */
1572 stof
= x86_expression(expr
->cond_false
);
1574 emit_copy(new, stof
, expr
->ctype
);
1576 /* end of conditional; jump target for if-true branch */
1577 emit_label(cond_end
, "end conditional");
1582 static struct storage
*emit_select_expr(struct expression
*expr
)
1584 struct storage
*cond
= x86_expression(expr
->conditional
);
1585 struct storage
*stot
= x86_expression(expr
->cond_true
);
1586 struct storage
*stof
= x86_expression(expr
->cond_false
);
1587 struct storage
*reg_cond
, *reg_true
, *reg_false
;
1588 struct storage
*new = stack_alloc(4);
1590 emit_comment("begin SELECT");
1591 reg_cond
= get_reg_value(cond
, get_regclass(expr
->conditional
));
1592 reg_true
= get_reg_value(stot
, get_regclass(expr
));
1593 reg_false
= get_reg_value(stof
, get_regclass(expr
));
1596 * Do the actual select: check the conditional for zero,
1597 * move false over true if zero
1599 insn("test", reg_cond
, reg_cond
, NULL
);
1600 insn("cmovz", reg_false
, reg_true
, NULL
);
1603 emit_move(reg_true
, new, expr
->ctype
, NULL
);
1607 emit_comment("end SELECT");
1611 static struct storage
*emit_symbol_expr_init(struct symbol
*sym
)
1613 struct expression
*expr
= sym
->initializer
;
1614 struct symbol_private
*priv
= sym
->aux
;
1617 priv
= calloc(1, sizeof(*priv
));
1621 struct storage
*new = stack_alloc(4);
1622 fprintf(stderr
, "FIXME! no value for symbol %s. creating pseudo %d (stack offset %d)\n",
1623 show_ident(sym
->ident
),
1624 new->pseudo
, new->pseudo
* 4);
1627 priv
->addr
= x86_expression(expr
);
1634 static struct storage
*emit_string_expr(struct expression
*expr
)
1636 struct function
*f
= current_func
;
1637 int label
= new_label();
1638 struct storage
*new;
1640 push_cstring(f
, expr
->string
, label
);
1642 new = new_storage(STOR_LABEL
);
1644 new->flags
= STOR_LABEL_VAL
| STOR_WANTS_FREE
;
1648 static struct storage
*emit_cast_expr(struct expression
*expr
)
1650 struct symbol
*old_type
, *new_type
;
1651 struct storage
*op
= x86_expression(expr
->cast_expression
);
1652 int oldbits
, newbits
;
1653 struct storage
*new;
1655 old_type
= expr
->cast_expression
->ctype
;
1656 new_type
= expr
->cast_type
;
1658 oldbits
= old_type
->bit_size
;
1659 newbits
= new_type
->bit_size
;
1660 if (oldbits
>= newbits
)
1663 emit_move(op
, REG_EAX
, old_type
, "begin cast ..");
1665 new = stack_alloc(newbits
/ 8);
1666 emit_move(REG_EAX
, new, new_type
, ".... end cast");
1671 static struct storage
*emit_regular_preop(struct expression
*expr
)
1673 struct storage
*target
= x86_expression(expr
->unop
);
1674 struct storage
*val
, *new = stack_alloc(4);
1675 const char *opname
= NULL
;
1679 val
= new_storage(STOR_VALUE
);
1680 val
->flags
= STOR_WANTS_FREE
;
1681 emit_move(val
, REG_EDX
, NULL
, NULL
);
1682 emit_move(target
, REG_EAX
, expr
->unop
->ctype
, NULL
);
1683 insn("test", REG_EAX
, REG_EAX
, NULL
);
1684 insn("setz", REG_DL
, NULL
, NULL
);
1685 emit_move(REG_EDX
, new, expr
->unop
->ctype
, NULL
);
1693 emit_move(target
, REG_EAX
, expr
->unop
->ctype
, NULL
);
1694 insn(opname
, REG_EAX
, NULL
, NULL
);
1695 emit_move(REG_EAX
, new, expr
->unop
->ctype
, NULL
);
1705 static void emit_case_statement(struct statement
*stmt
)
1707 emit_labelsym(stmt
->case_label
, NULL
);
1708 x86_statement(stmt
->case_statement
);
1711 static void emit_switch_statement(struct statement
*stmt
)
1713 struct storage
*val
= x86_expression(stmt
->switch_expression
);
1714 struct symbol
*sym
, *default_sym
= NULL
;
1715 struct storage
*labelsym
, *label
;
1718 emit_move(val
, REG_EAX
, stmt
->switch_expression
->ctype
, "begin case");
1721 * This is where a _real_ back-end would go through the
1722 * cases to decide whether to use a lookup table or a
1723 * series of comparisons etc
1725 FOR_EACH_PTR(stmt
->switch_case
->symbol_list
, sym
) {
1726 struct statement
*case_stmt
= sym
->stmt
;
1727 struct expression
*expr
= case_stmt
->case_expression
;
1728 struct expression
*to
= case_stmt
->case_to
;
1736 struct storage
*case_val
= new_val(expr
->value
);
1738 assert (expr
->type
== EXPR_VALUE
);
1740 insn("cmpl", case_val
, REG_EAX
, NULL
);
1743 labelsym
= new_labelsym(sym
);
1744 insn("je", labelsym
, NULL
, NULL
);
1748 label
= new_storage(STOR_LABEL
);
1749 label
->flags
|= STOR_WANTS_FREE
;
1750 label
->label
= next_test
= new_label();
1752 /* FIXME: signed/unsigned */
1753 insn("jl", label
, NULL
, NULL
);
1755 case_val
= new_val(to
->value
);
1756 insn("cmpl", case_val
, REG_EAX
, NULL
);
1758 /* TODO: implement and use refcounting... */
1759 label
= new_storage(STOR_LABEL
);
1760 label
->flags
|= STOR_WANTS_FREE
;
1761 label
->label
= next_test
;
1763 /* FIXME: signed/unsigned */
1764 insn("jg", label
, NULL
, NULL
);
1766 labelsym
= new_labelsym(sym
);
1767 insn("jmp", labelsym
, NULL
, NULL
);
1769 emit_label(next_test
, NULL
);
1772 } END_FOR_EACH_PTR(sym
);
1775 labelsym
= new_labelsym(default_sym
);
1776 insn("jmp", labelsym
, NULL
, "default");
1778 label
= new_storage(STOR_LABEL
);
1779 label
->flags
|= STOR_WANTS_FREE
;
1780 label
->label
= switch_end
= new_label();
1781 insn("jmp", label
, NULL
, "goto end of switch");
1784 x86_statement(stmt
->switch_statement
);
1786 if (stmt
->switch_break
->used
)
1787 emit_labelsym(stmt
->switch_break
, NULL
);
1790 emit_label(switch_end
, NULL
);
1793 static void x86_struct_member(struct symbol
*sym
)
1795 printf("\t%s:%d:%ld at offset %ld.%d", show_ident(sym
->ident
), sym
->bit_size
, sym
->ctype
.alignment
, sym
->offset
, sym
->bit_offset
);
1799 static void x86_symbol(struct symbol
*sym
)
1801 struct symbol
*type
;
1806 type
= sym
->ctype
.base_type
;
1811 * Show actual implementation information
1813 switch (type
->type
) {
1816 if (sym
->initializer
)
1819 emit_array_noinit(sym
);
1823 if (sym
->initializer
) {
1824 emit_object_pre(show_ident(sym
->ident
),
1825 sym
->ctype
.modifiers
,
1826 sym
->ctype
.alignment
,
1828 emit_scalar(sym
->initializer
, sym
->bit_size
);
1831 emit_scalar_noinit(sym
);
1836 struct symbol
*member
;
1839 FOR_EACH_PTR(type
->symbol_list
, member
) {
1840 x86_struct_member(member
);
1841 } END_FOR_EACH_PTR(member
);
1847 struct statement
*stmt
= type
->stmt
;
1850 x86_statement(stmt
);
1851 emit_func_post(sym
);
1860 if (sym
->initializer
&& (type
->type
!= SYM_BASETYPE
) &&
1861 (type
->type
!= SYM_ARRAY
)) {
1863 x86_expression(sym
->initializer
);
1867 static void x86_symbol_init(struct symbol
*sym
);
1869 static void x86_symbol_decl(struct symbol_list
*syms
)
1872 FOR_EACH_PTR(syms
, sym
) {
1873 x86_symbol_init(sym
);
1874 } END_FOR_EACH_PTR(sym
);
1877 static void loopstk_push(int cont_lbl
, int loop_bottom_lbl
)
1879 struct function
*f
= current_func
;
1880 struct loop_stack
*ls
;
1882 ls
= malloc(sizeof(*ls
));
1883 ls
->continue_lbl
= cont_lbl
;
1884 ls
->loop_bottom_lbl
= loop_bottom_lbl
;
1885 ls
->next
= f
->loop_stack
;
1889 static void loopstk_pop(void)
1891 struct function
*f
= current_func
;
1892 struct loop_stack
*ls
;
1894 assert(f
->loop_stack
!= NULL
);
1896 f
->loop_stack
= f
->loop_stack
->next
;
1900 static int loopstk_break(void)
1902 return current_func
->loop_stack
->loop_bottom_lbl
;
1905 static int loopstk_continue(void)
1907 return current_func
->loop_stack
->continue_lbl
;
1910 static void emit_loop(struct statement
*stmt
)
1912 struct statement
*pre_statement
= stmt
->iterator_pre_statement
;
1913 struct expression
*pre_condition
= stmt
->iterator_pre_condition
;
1914 struct statement
*statement
= stmt
->iterator_statement
;
1915 struct statement
*post_statement
= stmt
->iterator_post_statement
;
1916 struct expression
*post_condition
= stmt
->iterator_post_condition
;
1917 int loop_top
= 0, loop_bottom
, loop_continue
;
1918 int have_bottom
= 0;
1919 struct storage
*val
;
1921 loop_bottom
= new_label();
1922 loop_continue
= new_label();
1923 loopstk_push(loop_continue
, loop_bottom
);
1925 x86_symbol_decl(stmt
->iterator_syms
);
1926 x86_statement(pre_statement
);
1927 if (!post_condition
|| post_condition
->type
!= EXPR_VALUE
|| post_condition
->value
) {
1928 loop_top
= new_label();
1929 emit_label(loop_top
, "loop top");
1931 if (pre_condition
) {
1932 if (pre_condition
->type
== EXPR_VALUE
) {
1933 if (!pre_condition
->value
) {
1934 struct storage
*lbv
;
1935 lbv
= new_storage(STOR_LABEL
);
1936 lbv
->label
= loop_bottom
;
1937 lbv
->flags
= STOR_WANTS_FREE
;
1938 insn("jmp", lbv
, NULL
, "go to loop bottom");
1942 struct storage
*lbv
= new_storage(STOR_LABEL
);
1943 lbv
->label
= loop_bottom
;
1944 lbv
->flags
= STOR_WANTS_FREE
;
1947 val
= x86_expression(pre_condition
);
1949 emit_move(val
, REG_EAX
, NULL
, "loop pre condition");
1950 insn("test", REG_EAX
, REG_EAX
, NULL
);
1951 insn("jz", lbv
, NULL
, NULL
);
1954 x86_statement(statement
);
1955 if (stmt
->iterator_continue
->used
)
1956 emit_label(loop_continue
, "'continue' iterator");
1957 x86_statement(post_statement
);
1958 if (!post_condition
) {
1959 struct storage
*lbv
= new_storage(STOR_LABEL
);
1960 lbv
->label
= loop_top
;
1961 lbv
->flags
= STOR_WANTS_FREE
;
1962 insn("jmp", lbv
, NULL
, "go to loop top");
1963 } else if (post_condition
->type
== EXPR_VALUE
) {
1964 if (post_condition
->value
) {
1965 struct storage
*lbv
= new_storage(STOR_LABEL
);
1966 lbv
->label
= loop_top
;
1967 lbv
->flags
= STOR_WANTS_FREE
;
1968 insn("jmp", lbv
, NULL
, "go to loop top");
1971 struct storage
*lbv
= new_storage(STOR_LABEL
);
1972 lbv
->label
= loop_top
;
1973 lbv
->flags
= STOR_WANTS_FREE
;
1975 val
= x86_expression(post_condition
);
1977 emit_move(val
, REG_EAX
, NULL
, "loop post condition");
1978 insn("test", REG_EAX
, REG_EAX
, NULL
);
1979 insn("jnz", lbv
, NULL
, NULL
);
1981 if (have_bottom
|| stmt
->iterator_break
->used
)
1982 emit_label(loop_bottom
, "loop bottom");
1988 * Print out a statement
1990 static struct storage
*x86_statement(struct statement
*stmt
)
1994 switch (stmt
->type
) {
1998 return emit_return_stmt(stmt
);
1999 case STMT_DECLARATION
:
2000 x86_symbol_decl(stmt
->declaration
);
2002 case STMT_COMPOUND
: {
2003 struct statement
*s
;
2004 struct storage
*last
= NULL
;
2006 FOR_EACH_PTR(stmt
->stmts
, s
) {
2007 last
= x86_statement(s
);
2008 } END_FOR_EACH_PTR(s
);
2013 case STMT_EXPRESSION
:
2014 return x86_expression(stmt
->expression
);
2016 emit_if_conditional(stmt
);
2020 emit_case_statement(stmt
);
2023 emit_switch_statement(stmt
);
2034 printf(".L%p:\n", stmt
->label_identifier
);
2035 x86_statement(stmt
->label_statement
);
2039 if (stmt
->goto_expression
) {
2040 struct storage
*val
= x86_expression(stmt
->goto_expression
);
2041 printf("\tgoto *v%d\n", val
->pseudo
);
2042 } else if (!strcmp("break", show_ident(stmt
->goto_label
->ident
))) {
2043 struct storage
*lbv
= new_storage(STOR_LABEL
);
2044 lbv
->label
= loopstk_break();
2045 lbv
->flags
= STOR_WANTS_FREE
;
2046 insn("jmp", lbv
, NULL
, "'break'; go to loop bottom");
2047 } else if (!strcmp("continue", show_ident(stmt
->goto_label
->ident
))) {
2048 struct storage
*lbv
= new_storage(STOR_LABEL
);
2049 lbv
->label
= loopstk_continue();
2050 lbv
->flags
= STOR_WANTS_FREE
;
2051 insn("jmp", lbv
, NULL
, "'continue'; go to loop top");
2053 struct storage
*labelsym
= new_labelsym(stmt
->goto_label
);
2054 insn("jmp", labelsym
, NULL
, NULL
);
2058 printf("\tasm( .... )\n");
2064 static struct storage
*x86_call_expression(struct expression
*expr
)
2066 struct function
*f
= current_func
;
2067 struct symbol
*direct
;
2068 struct expression
*arg
, *fn
;
2069 struct storage
*retval
, *fncall
;
2074 warning(expr
->pos
, "\tcall with no type!");
2079 FOR_EACH_PTR_REVERSE(expr
->args
, arg
) {
2080 struct storage
*new = x86_expression(arg
);
2081 int size
= arg
->ctype
->bit_size
;
2084 * FIXME: i386 SysV ABI dictates that values
2085 * smaller than 32 bits should be placed onto
2086 * the stack as 32-bit objects. We should not
2087 * blindly do a 32-bit push on objects smaller
2092 insn("pushl", new, NULL
,
2093 !framesize
? "begin function call" : NULL
);
2095 framesize
+= bits_to_bytes(size
);
2096 } END_FOR_EACH_PTR_REVERSE(arg
);
2100 /* Remove dereference, if any */
2102 if (fn
->type
== EXPR_PREOP
) {
2103 if (fn
->unop
->type
== EXPR_SYMBOL
) {
2104 struct symbol
*sym
= fn
->unop
->symbol
;
2105 if (sym
->ctype
.base_type
->type
== SYM_FN
)
2110 struct storage
*direct_stor
= new_storage(STOR_SYM
);
2111 direct_stor
->flags
|= STOR_WANTS_FREE
;
2112 direct_stor
->sym
= direct
;
2113 insn("call", direct_stor
, NULL
, NULL
);
2115 fncall
= x86_expression(fn
);
2116 emit_move(fncall
, REG_EAX
, fn
->ctype
, NULL
);
2118 strcpy(s
, "\tcall\t*%eax\n");
2119 push_text_atom(f
, s
);
2122 /* FIXME: pay attention to BITS_IN_POINTER */
2124 struct storage
*val
= new_storage(STOR_VALUE
);
2125 val
->value
= (long long) framesize
;
2126 val
->flags
= STOR_WANTS_FREE
;
2127 insn("addl", val
, REG_ESP
, NULL
);
2130 retval
= stack_alloc(4);
2131 emit_move(REG_EAX
, retval
, NULL
, "end function call");
2136 static struct storage
*x86_address_gen(struct expression
*expr
)
2138 struct function
*f
= current_func
;
2139 struct storage
*addr
;
2140 struct storage
*new;
2143 addr
= x86_expression(expr
->unop
);
2144 if (expr
->unop
->type
== EXPR_SYMBOL
)
2147 emit_move(addr
, REG_EAX
, NULL
, "begin deref ..");
2149 /* FIXME: operand size */
2150 strcpy(s
, "\tmovl\t(%eax), %ecx\n");
2151 push_text_atom(f
, s
);
2153 new = stack_alloc(4);
2154 emit_move(REG_ECX
, new, NULL
, ".... end deref");
2159 static struct storage
*x86_assignment(struct expression
*expr
)
2161 struct expression
*target
= expr
->left
;
2162 struct storage
*val
, *addr
;
2167 val
= x86_expression(expr
->right
);
2168 addr
= x86_address_gen(target
);
2170 switch (val
->type
) {
2171 /* copy, where both operands are memory */
2174 emit_copy(addr
, val
, expr
->ctype
);
2177 /* copy, one or zero operands are memory */
2182 emit_move(val
, addr
, expr
->left
->ctype
, NULL
);
2192 static int x86_initialization(struct symbol
*sym
, struct expression
*expr
)
2194 struct storage
*val
, *addr
;
2200 bits
= expr
->ctype
->bit_size
;
2201 val
= x86_expression(expr
);
2202 addr
= x86_symbol_expr(sym
);
2203 // FIXME! The "target" expression is for bitfield store information.
2204 // Leave it NULL, which works fine.
2205 emit_store(NULL
, addr
, val
, bits
);
2209 static struct storage
*x86_access(struct expression
*expr
)
2211 return x86_address_gen(expr
);
2214 static struct storage
*x86_preop(struct expression
*expr
)
2217 * '*' is an lvalue access, and is fundamentally different
2218 * from an arithmetic operation. Maybe it should have an
2219 * expression type of its own..
2221 if (expr
->op
== '*')
2222 return x86_access(expr
);
2223 if (expr
->op
== SPECIAL_INCREMENT
|| expr
->op
== SPECIAL_DECREMENT
)
2224 return emit_inc_dec(expr
, 0);
2225 return emit_regular_preop(expr
);
2228 static struct storage
*x86_symbol_expr(struct symbol
*sym
)
2230 struct storage
*new = stack_alloc(4);
2232 if (sym
->ctype
.modifiers
& (MOD_TOPLEVEL
| MOD_EXTERN
| MOD_STATIC
)) {
2233 printf("\tmovi.%d\t\tv%d,$%s\n", bits_in_pointer
, new->pseudo
, show_ident(sym
->ident
));
2236 if (sym
->ctype
.modifiers
& MOD_ADDRESSABLE
) {
2237 printf("\taddi.%d\t\tv%d,vFP,$%lld\n", bits_in_pointer
, new->pseudo
, 0LL);
2240 printf("\taddi.%d\t\tv%d,vFP,$offsetof(%s:%p)\n", bits_in_pointer
, new->pseudo
, show_ident(sym
->ident
), sym
);
2244 static void x86_symbol_init(struct symbol
*sym
)
2246 struct symbol_private
*priv
= sym
->aux
;
2247 struct expression
*expr
= sym
->initializer
;
2248 struct storage
*new;
2251 new = x86_expression(expr
);
2253 new = stack_alloc(sym
->bit_size
/ 8);
2256 priv
= calloc(1, sizeof(*priv
));
2258 /* FIXME: leak! we don't free... */
2259 /* (well, we don't free symbols either) */
2265 static struct storage
*x86_label_expr(struct expression
*expr
)
2267 struct storage
*new = stack_alloc(4);
2268 printf("\tmovi.%d\t\tv%d,.L%p\n", bits_in_pointer
, new->pseudo
, expr
->label_symbol
);
2272 static struct storage
*x86_statement_expr(struct expression
*expr
)
2274 return x86_statement(expr
->statement
);
2277 static int x86_position_expr(struct expression
*expr
, struct symbol
*base
)
2279 struct storage
*new = x86_expression(expr
->init_expr
);
2280 struct symbol
*ctype
= expr
->init_expr
->ctype
;
2282 printf("\tinsert v%d at [%d:%d] of %s\n", new->pseudo
,
2283 expr
->init_offset
, ctype
->bit_offset
,
2284 show_ident(base
->ident
));
2288 static void x86_initializer_expr(struct expression
*expr
, struct symbol
*ctype
)
2290 struct expression
*entry
;
2292 FOR_EACH_PTR(expr
->expr_list
, entry
) {
2293 // Nested initializers have their positions already
2294 // recursively calculated - just output them too
2295 if (entry
->type
== EXPR_INITIALIZER
) {
2296 x86_initializer_expr(entry
, ctype
);
2300 // Ignore initializer indexes and identifiers - the
2301 // evaluator has taken them into account
2302 if (entry
->type
== EXPR_IDENTIFIER
|| entry
->type
== EXPR_INDEX
)
2304 if (entry
->type
== EXPR_POS
) {
2305 x86_position_expr(entry
, ctype
);
2308 x86_initialization(ctype
, entry
);
2309 } END_FOR_EACH_PTR(entry
);
2313 * Print out an expression. Return the pseudo that contains the
2316 static struct storage
*x86_expression(struct expression
*expr
)
2322 struct position
*pos
= &expr
->pos
;
2323 printf("\tno type at %s:%d:%d\n",
2324 stream_name(pos
->stream
),
2325 pos
->line
, pos
->pos
);
2329 switch (expr
->type
) {
2333 return x86_call_expression(expr
);
2335 case EXPR_ASSIGNMENT
:
2336 return x86_assignment(expr
);
2339 return emit_compare(expr
);
2343 return emit_binop(expr
);
2345 return x86_preop(expr
);
2347 return emit_postop(expr
);
2349 return emit_symbol_expr_init(expr
->symbol
);
2353 warning(expr
->pos
, "invalid expression after evaluation");
2356 case EXPR_FORCE_CAST
:
2357 case EXPR_IMPLIED_CAST
:
2358 return emit_cast_expr(expr
);
2360 return emit_value(expr
);
2362 return emit_string_expr(expr
);
2363 case EXPR_INITIALIZER
:
2364 x86_initializer_expr(expr
, expr
->ctype
);
2367 return emit_select_expr(expr
);
2368 case EXPR_CONDITIONAL
:
2369 return emit_conditional_expr(expr
);
2370 case EXPR_STATEMENT
:
2371 return x86_statement_expr(expr
);
2373 return x86_label_expr(expr
);
2375 // None of these should exist as direct expressions: they are only
2376 // valid as sub-expressions of initializers.
2378 warning(expr
->pos
, "unable to show plain initializer position expression");
2380 case EXPR_IDENTIFIER
:
2381 warning(expr
->pos
, "unable to show identifier expression");
2384 warning(expr
->pos
, "unable to show index expression");
2387 warning(expr
->pos
, "unable to show type expression");
2390 warning(expr
->pos
, "floating point support is not implemented");