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"
63 unsigned int len
; /* does NOT include terminating null */
72 struct loop_stack
*next
;
77 DECLARE_PTR_LIST(str_list
, struct atom
);
78 DECLARE_PTR_LIST(atom_list
, struct atom
);
79 DECLARE_PTR_LIST(storage_list
, struct storage
);
84 struct storage_list
*pseudo_list
;
85 struct atom_list
*atom_list
;
86 struct str_list
*str_list
;
87 struct loop_stack
*loop_stack
;
94 STOR_PSEUDO
, /* variable stored on the stack */
95 STOR_ARG
, /* function argument */
96 STOR_SYM
, /* a symbol we can directly ref in the asm */
97 STOR_REG
, /* scratch register */
98 STOR_VALUE
, /* integer constant */
99 STOR_LABEL
, /* label / jump target */
100 STOR_LABELSYM
, /* label generated from symbol's pointer value */
105 struct storage
*contains
;
106 const unsigned char aliases
[12];
107 #define own_regno aliases[0]
111 enum storage_type type
;
115 struct reg_info
*reg
;
116 struct symbol
*ctype
;
143 struct symbol
*labelsym
;
149 STOR_LABEL_VAL
= (1 << 0),
150 STOR_WANTS_FREE
= (1 << 1),
153 struct symbol_private
{
154 struct storage
*addr
;
169 unsigned int text_len
; /* w/o terminating null */
172 /* stuff for insns */
180 /* stuff for C strings */
182 struct string
*string
;
189 static struct function
*current_func
= NULL
;
190 static struct textbuf
*unit_post_text
= NULL
;
191 static const char *current_section
;
193 static void emit_comment(const char * fmt
, ...) FORMAT_ATTR(1);
194 static void emit_move(struct storage
*src
, struct storage
*dest
,
195 struct symbol
*ctype
, const char *comment
);
196 static int type_is_signed(struct symbol
*sym
);
197 static struct storage
*x86_address_gen(struct expression
*expr
);
198 static struct storage
*x86_symbol_expr(struct symbol
*sym
);
199 static void x86_symbol(struct symbol
*sym
);
200 static struct storage
*x86_statement(struct statement
*stmt
);
201 static struct storage
*x86_expression(struct expression
*expr
);
205 AL
, DL
, CL
, BL
, AH
, DH
, CH
, BH
, // 8-bit
206 AX
, DX
, CX
, BX
, SI
, DI
, BP
, SP
, // 16-bit
207 EAX
, EDX
, ECX
, EBX
, ESI
, EDI
, EBP
, ESP
, // 32-bit
208 EAX_EDX
, ECX_EBX
, ESI_EDI
, // 64-bit
211 /* This works on regno's, reg_info's and hardreg_storage's */
212 #define byte_reg(reg) ((reg) - 16)
213 #define highbyte_reg(reg) ((reg)-12)
214 #define word_reg(reg) ((reg)-8)
216 #define REGINFO(nr, str, conflicts...) [nr] = { .name = str, .aliases = { nr , conflicts } }
218 static struct reg_info reg_info_table
[] = {
219 REGINFO( AL
, "%al", AX
, EAX
, EAX_EDX
),
220 REGINFO( DL
, "%dl", DX
, EDX
, EAX_EDX
),
221 REGINFO( CL
, "%cl", CX
, ECX
, ECX_EBX
),
222 REGINFO( BL
, "%bl", BX
, EBX
, ECX_EBX
),
223 REGINFO( AH
, "%ah", AX
, EAX
, EAX_EDX
),
224 REGINFO( DH
, "%dh", DX
, EDX
, EAX_EDX
),
225 REGINFO( CH
, "%ch", CX
, ECX
, ECX_EBX
),
226 REGINFO( BH
, "%bh", BX
, EBX
, ECX_EBX
),
227 REGINFO( AX
, "%ax", AL
, AH
, EAX
, EAX_EDX
),
228 REGINFO( DX
, "%dx", DL
, DH
, EDX
, EAX_EDX
),
229 REGINFO( CX
, "%cx", CL
, CH
, ECX
, ECX_EBX
),
230 REGINFO( BX
, "%bx", BL
, BH
, EBX
, ECX_EBX
),
231 REGINFO( SI
, "%si", ESI
, ESI_EDI
),
232 REGINFO( DI
, "%di", EDI
, ESI_EDI
),
233 REGINFO( BP
, "%bp", EBP
),
234 REGINFO( SP
, "%sp", ESP
),
235 REGINFO(EAX
, "%eax", AL
, AH
, AX
, EAX_EDX
),
236 REGINFO(EDX
, "%edx", DL
, DH
, DX
, EAX_EDX
),
237 REGINFO(ECX
, "%ecx", CL
, CH
, CX
, ECX_EBX
),
238 REGINFO(EBX
, "%ebx", BL
, BH
, BX
, ECX_EBX
),
239 REGINFO(ESI
, "%esi", SI
, ESI_EDI
),
240 REGINFO(EDI
, "%edi", DI
, ESI_EDI
),
241 REGINFO(EBP
, "%ebp", BP
),
242 REGINFO(ESP
, "%esp", SP
),
243 REGINFO(EAX_EDX
, "%eax:%edx", AL
, AH
, AX
, EAX
, DL
, DH
, DX
, EDX
),
244 REGINFO(ECX_EBX
, "%ecx:%ebx", CL
, CH
, CX
, ECX
, BL
, BH
, BX
, EBX
),
245 REGINFO(ESI_EDI
, "%esi:%edi", SI
, ESI
, DI
, EDI
),
248 #define REGSTORAGE(nr) [nr] = { .type = STOR_REG, .reg = reg_info_table + (nr) }
250 static struct storage hardreg_storage_table
[] = {
251 REGSTORAGE(AL
), REGSTORAGE(DL
), REGSTORAGE(CL
), REGSTORAGE(BL
),
252 REGSTORAGE(AH
), REGSTORAGE(DH
), REGSTORAGE(CH
), REGSTORAGE(BH
),
253 REGSTORAGE(AX
), REGSTORAGE(DX
), REGSTORAGE(CX
), REGSTORAGE(BX
),
254 REGSTORAGE(SI
), REGSTORAGE(DI
), REGSTORAGE(BP
), REGSTORAGE(SP
),
255 REGSTORAGE(EAX
), REGSTORAGE(EDX
), REGSTORAGE(ECX
), REGSTORAGE(EBX
),
256 REGSTORAGE(ESI
), REGSTORAGE(EDI
), REGSTORAGE(EBP
), REGSTORAGE(ESP
),
257 REGSTORAGE(EAX_EDX
), REGSTORAGE(ECX_EBX
), REGSTORAGE(ESI_EDI
),
260 #define REG_EAX (&hardreg_storage_table[EAX])
261 #define REG_ECX (&hardreg_storage_table[ECX])
262 #define REG_EDX (&hardreg_storage_table[EDX])
263 #define REG_ESP (&hardreg_storage_table[ESP])
264 #define REG_DL (&hardreg_storage_table[DL])
265 #define REG_DX (&hardreg_storage_table[DX])
266 #define REG_AL (&hardreg_storage_table[AL])
267 #define REG_AX (&hardreg_storage_table[AX])
269 static DECLARE_BITMAP(regs_in_use
, 256);
271 static inline struct storage
* reginfo_reg(struct reg_info
*info
)
273 return hardreg_storage_table
+ info
->own_regno
;
276 static struct storage
* get_hardreg(struct storage
*reg
, int clear
)
278 struct reg_info
*info
= reg
->reg
;
279 const unsigned char *aliases
;
282 aliases
= info
->aliases
;
283 while ((regno
= *aliases
++) != NOREG
) {
284 if (test_bit(regno
, regs_in_use
))
287 reg_info_table
[regno
].contains
= NULL
;
289 set_bit(info
->own_regno
, regs_in_use
);
292 fprintf(stderr
, "register %s is busy\n", info
->name
);
293 if (regno
+ reg_info_table
!= info
)
294 fprintf(stderr
, " conflicts with %s\n", reg_info_table
[regno
].name
);
298 static void put_reg(struct storage
*reg
)
300 struct reg_info
*info
= reg
->reg
;
301 int regno
= info
->own_regno
;
303 if (test_and_clear_bit(regno
, regs_in_use
))
305 fprintf(stderr
, "freeing already free'd register %s\n", reg_info_table
[regno
].name
);
310 const unsigned char regs
[30];
313 static struct regclass regclass_8
= { "8-bit", { AL
, DL
, CL
, BL
, AH
, DH
, CH
, BH
}};
314 static struct regclass regclass_16
= { "16-bit", { AX
, DX
, CX
, BX
, SI
, DI
, BP
}};
315 static struct regclass regclass_32
= { "32-bit", { EAX
, EDX
, ECX
, EBX
, ESI
, EDI
, EBP
}};
316 static struct regclass regclass_64
= { "64-bit", { EAX_EDX
, ECX_EBX
, ESI_EDI
}};
318 static struct regclass regclass_32_8
= { "32-bit bytes", { EAX
, EDX
, ECX
, EBX
}};
320 static struct regclass
*get_regclass_bits(int bits
)
323 case 8: return ®class_8
;
324 case 16: return ®class_16
;
325 case 64: return ®class_64
;
326 default: return ®class_32
;
330 static struct regclass
*get_regclass(struct expression
*expr
)
332 return get_regclass_bits(expr
->ctype
->bit_size
);
335 static int register_busy(int regno
)
337 if (!test_bit(regno
, regs_in_use
)) {
338 struct reg_info
*info
= reg_info_table
+ regno
;
339 const unsigned char *regs
= info
->aliases
+1;
341 while ((regno
= *regs
) != NOREG
) {
343 if (test_bit(regno
, regs_in_use
))
352 static struct storage
*get_reg(struct regclass
*class)
354 const unsigned char *regs
= class->regs
;
357 while ((regno
= *regs
) != NOREG
) {
359 if (register_busy(regno
))
361 return get_hardreg(hardreg_storage_table
+ regno
, 1);
363 fprintf(stderr
, "Ran out of %s registers\n", class->name
);
367 static struct storage
*get_reg_value(struct storage
*value
, struct regclass
*class)
369 struct reg_info
*info
;
372 /* Do we already have it somewhere */
374 if (info
&& info
->contains
== value
) {
375 emit_comment("already have register %s", info
->name
);
376 return get_hardreg(hardreg_storage_table
+ info
->own_regno
, 0);
379 reg
= get_reg(class);
380 emit_move(value
, reg
, value
->ctype
, "reload register");
382 info
->contains
= value
;
387 static struct storage
*temp_from_bits(unsigned int bit_size
)
389 return get_reg(get_regclass_bits(bit_size
));
392 static inline unsigned int pseudo_offset(struct storage
*s
)
394 if (s
->type
!= STOR_PSEUDO
)
395 return 123456; /* intentionally bogus value */
400 static inline unsigned int arg_offset(struct storage
*s
)
402 if (s
->type
!= STOR_ARG
)
403 return 123456; /* intentionally bogus value */
405 /* FIXME: this is wrong wrong wrong */
406 return current_func
->stack_size
+ ((1 + s
->idx
) * 4);
409 static const char *pretty_offset(int ofs
)
411 static char esp_buf
[64];
414 sprintf(esp_buf
, "%d(%%esp)", ofs
);
416 strcpy(esp_buf
, "(%esp)");
421 static void stor_sym_init(struct symbol
*sym
)
423 struct storage
*stor
;
424 struct symbol_private
*priv
;
426 priv
= calloc(1, sizeof(*priv
) + sizeof(*stor
));
428 die("OOM in stor_sym_init");
430 stor
= (struct storage
*) (priv
+ 1);
433 stor
->type
= STOR_SYM
;
437 static const char *stor_op_name(struct storage
*s
)
439 static char name
[32];
443 strcpy(name
, pretty_offset((int) pseudo_offset(s
)));
446 strcpy(name
, pretty_offset((int) arg_offset(s
)));
449 strcpy(name
, show_ident(s
->sym
->ident
));
452 strcpy(name
, s
->reg
->name
);
455 sprintf(name
, "$%Ld", s
->value
);
458 sprintf(name
, "%s.L%d", s
->flags
& STOR_LABEL_VAL
? "$" : "",
462 sprintf(name
, "%s.LS%p", s
->flags
& STOR_LABEL_VAL
? "$" : "",
470 static struct atom
*new_atom(enum atom_type type
)
474 atom
= calloc(1, sizeof(*atom
)); /* TODO: chunked alloc */
483 static inline void push_cstring(struct function
*f
, struct string
*str
,
488 atom
= new_atom(ATOM_CSTR
);
492 add_ptr_list(&f
->str_list
, atom
); /* note: _not_ atom_list */
495 static inline void push_atom(struct function
*f
, struct atom
*atom
)
497 add_ptr_list(&f
->atom_list
, atom
);
500 static void push_text_atom(struct function
*f
, const char *text
)
502 struct atom
*atom
= new_atom(ATOM_TEXT
);
504 atom
->text
= strdup(text
);
505 atom
->text_len
= strlen(text
);
510 static struct storage
*new_storage(enum storage_type type
)
512 struct storage
*stor
;
514 stor
= calloc(1, sizeof(*stor
));
516 die("OOM in new_storage");
523 static struct storage
*stack_alloc(int n_bytes
)
525 struct function
*f
= current_func
;
526 struct storage
*stor
;
530 stor
= new_storage(STOR_PSEUDO
);
531 stor
->type
= STOR_PSEUDO
;
532 stor
->pseudo
= f
->pseudo_nr
;
533 stor
->offset
= f
->stack_size
; /* FIXME: stack req. natural align */
534 stor
->size
= n_bytes
;
535 f
->stack_size
+= n_bytes
;
538 add_ptr_list(&f
->pseudo_list
, stor
);
543 static struct storage
*new_labelsym(struct symbol
*sym
)
545 struct storage
*stor
;
547 stor
= new_storage(STOR_LABELSYM
);
550 stor
->flags
|= STOR_WANTS_FREE
;
551 stor
->labelsym
= sym
;
557 static struct storage
*new_val(long long value
)
559 struct storage
*stor
;
561 stor
= new_storage(STOR_VALUE
);
564 stor
->flags
|= STOR_WANTS_FREE
;
571 static int new_label(void)
573 static int label
= 0;
577 static void textbuf_push(struct textbuf
**buf_p
, const char *text
)
579 struct textbuf
*tmp
, *list
= *buf_p
;
580 unsigned int text_len
= strlen(text
);
581 unsigned int alloc_len
= text_len
+ 1 + sizeof(*list
);
583 tmp
= calloc(1, alloc_len
);
585 die("OOM on textbuf alloc");
587 tmp
->text
= ((void *) tmp
) + sizeof(*tmp
);
588 memcpy(tmp
->text
, text
, text_len
+ 1);
591 /* add to end of list */
596 tmp
->prev
= list
->prev
;
597 tmp
->prev
->next
= tmp
;
605 static void textbuf_emit(struct textbuf
**buf_p
)
607 struct textbuf
*tmp
, *list
= *buf_p
;
611 if (tmp
->next
== tmp
)
614 tmp
->prev
->next
= tmp
->next
;
615 tmp
->next
->prev
= tmp
->prev
;
619 fputs(tmp
->text
, stdout
);
627 static void insn(const char *insn
, struct storage
*op1
, struct storage
*op2
,
628 const char *comment_in
)
630 struct function
*f
= current_func
;
631 struct atom
*atom
= new_atom(ATOM_INSN
);
633 assert(insn
!= NULL
);
635 strcpy(atom
->insn
, insn
);
636 if (comment_in
&& (*comment_in
))
637 strncpy(atom
->comment
, comment_in
,
638 sizeof(atom
->comment
) - 1);
646 static void emit_comment(const char *fmt
, ...)
648 struct function
*f
= current_func
;
649 static char tmpbuf
[100] = "\t# ";
654 i
= vsnprintf(tmpbuf
+3, sizeof(tmpbuf
)-4, fmt
, args
);
658 push_text_atom(f
, tmpbuf
);
661 static void emit_label (int label
, const char *comment
)
663 struct function
*f
= current_func
;
667 sprintf(s
, ".L%d:\n", label
);
669 sprintf(s
, ".L%d:\t\t\t\t\t# %s\n", label
, comment
);
671 push_text_atom(f
, s
);
674 static void emit_labelsym (struct symbol
*sym
, const char *comment
)
676 struct function
*f
= current_func
;
680 sprintf(s
, ".LS%p:\n", sym
);
682 sprintf(s
, ".LS%p:\t\t\t\t# %s\n", sym
, comment
);
684 push_text_atom(f
, s
);
687 void emit_unit_begin(const char *basename
)
689 printf("\t.file\t\"%s\"\n", basename
);
692 void emit_unit_end(void)
694 textbuf_emit(&unit_post_text
);
695 printf("\t.ident\t\"sparse silly x86 backend (version %s)\"\n", SPARSE_VERSION
);
698 /* conditionally switch sections */
699 static void emit_section(const char *s
)
701 if (s
== current_section
)
703 if (current_section
&& (!strcmp(s
, current_section
)))
710 static void emit_insn_atom(struct function
*f
, struct atom
*atom
)
714 struct storage
*op1
= atom
->op1
;
715 struct storage
*op2
= atom
->op2
;
717 if (atom
->comment
[0])
718 sprintf(comment
, "\t\t# %s", atom
->comment
);
724 strcpy(tmp
, stor_op_name(op1
));
725 sprintf(s
, "\t%s\t%s, %s%s\n",
726 atom
->insn
, tmp
, stor_op_name(op2
), comment
);
727 } else if (atom
->op1
)
728 sprintf(s
, "\t%s\t%s%s%s\n",
729 atom
->insn
, stor_op_name(op1
),
730 comment
[0] ? "\t" : "", comment
);
732 sprintf(s
, "\t%s\t%s%s\n",
734 comment
[0] ? "\t\t" : "", comment
);
736 if (write(STDOUT_FILENO
, s
, strlen(s
)) < 0)
737 die("can't write to stdout");
740 static void emit_atom_list(struct function
*f
)
744 FOR_EACH_PTR(f
->atom_list
, atom
) {
745 switch (atom
->type
) {
747 if (write(STDOUT_FILENO
, atom
->text
, atom
->text_len
) < 0)
748 die("can't write to stdout");
752 emit_insn_atom(f
, atom
);
758 } END_FOR_EACH_PTR(atom
);
761 static void emit_string_list(struct function
*f
)
765 emit_section(".section\t.rodata");
767 FOR_EACH_PTR(f
->str_list
, atom
) {
768 /* FIXME: escape " in string */
769 printf(".L%d:\n", atom
->label
);
770 printf("\t.string\t%s\n", show_string(atom
->string
));
773 } END_FOR_EACH_PTR(atom
);
776 static void func_cleanup(struct function
*f
)
778 struct storage
*stor
;
781 FOR_EACH_PTR(f
->atom_list
, atom
) {
782 if ((atom
->type
== ATOM_TEXT
) && (atom
->text
))
784 if (atom
->op1
&& (atom
->op1
->flags
& STOR_WANTS_FREE
))
786 if (atom
->op2
&& (atom
->op2
->flags
& STOR_WANTS_FREE
))
789 } END_FOR_EACH_PTR(atom
);
791 FOR_EACH_PTR(f
->pseudo_list
, stor
) {
793 } END_FOR_EACH_PTR(stor
);
795 free_ptr_list(&f
->pseudo_list
);
799 /* function prologue */
800 static void emit_func_pre(struct symbol
*sym
)
804 unsigned int i
, argc
= 0, alloc_len
;
806 struct symbol_private
*privbase
;
807 struct storage
*storage_base
;
808 struct symbol
*base_type
= sym
->ctype
.base_type
;
810 FOR_EACH_PTR(base_type
->arguments
, arg
) {
812 } END_FOR_EACH_PTR(arg
);
816 (argc
* sizeof(struct symbol
*)) +
817 (argc
* sizeof(struct symbol_private
)) +
818 (argc
* sizeof(struct storage
));
819 mem
= calloc(1, alloc_len
);
821 die("OOM on func info");
823 f
= (struct function
*) mem
;
825 f
->argv
= (struct symbol
**) mem
;
826 mem
+= (argc
* sizeof(struct symbol
*));
827 privbase
= (struct symbol_private
*) mem
;
828 mem
+= (argc
* sizeof(struct symbol_private
));
829 storage_base
= (struct storage
*) mem
;
832 f
->ret_target
= new_label();
835 FOR_EACH_PTR(base_type
->arguments
, arg
) {
837 arg
->aux
= &privbase
[i
];
838 storage_base
[i
].type
= STOR_ARG
;
839 storage_base
[i
].idx
= i
;
840 privbase
[i
].addr
= &storage_base
[i
];
842 } END_FOR_EACH_PTR(arg
);
844 assert(current_func
== NULL
);
848 /* function epilogue */
849 static void emit_func_post(struct symbol
*sym
)
851 const char *name
= show_ident(sym
->ident
);
852 struct function
*f
= current_func
;
853 int stack_size
= f
->stack_size
;
858 /* function prologue */
859 emit_section(".text");
860 if ((sym
->ctype
.modifiers
& MOD_STATIC
) == 0)
861 printf(".globl %s\n", name
);
862 printf("\t.type\t%s, @function\n", name
);
863 printf("%s:\n", name
);
866 char pseudo_const
[16];
868 sprintf(pseudo_const
, "$%d", stack_size
);
869 printf("\tsubl\t%s, %%esp\n", pseudo_const
);
872 /* function epilogue */
874 /* jump target for 'return' statements */
875 emit_label(f
->ret_target
, NULL
);
880 val
= new_storage(STOR_VALUE
);
881 val
->value
= (long long) (stack_size
);
882 val
->flags
= STOR_WANTS_FREE
;
884 insn("addl", val
, REG_ESP
, NULL
);
887 insn("ret", NULL
, NULL
, NULL
);
889 /* output everything to stdout */
890 fflush(stdout
); /* paranoia; needed? */
893 /* function footer */
894 name
= show_ident(sym
->ident
);
895 printf("\t.size\t%s, .-%s\n", name
, name
);
901 /* emit object (a.k.a. variable, a.k.a. data) prologue */
902 static void emit_object_pre(const char *name
, unsigned long modifiers
,
903 unsigned long alignment
, unsigned int byte_size
)
905 if ((modifiers
& MOD_STATIC
) == 0)
906 printf(".globl %s\n", name
);
907 emit_section(".data");
909 printf("\t.align %lu\n", alignment
);
910 printf("\t.type\t%s, @object\n", name
);
911 printf("\t.size\t%s, %d\n", name
, byte_size
);
912 printf("%s:\n", name
);
915 /* emit value (only) for an initializer scalar */
916 static void emit_scalar(struct expression
*expr
, unsigned int bit_size
)
921 assert(expr
->type
== EXPR_VALUE
);
923 if (expr
->value
== 0ULL) {
924 printf("\t.zero\t%d\n", bit_size
/ 8);
928 ll
= (long long) expr
->value
;
931 case 8: type
= "byte"; ll
= (char) ll
; break;
932 case 16: type
= "value"; ll
= (short) ll
; break;
933 case 32: type
= "long"; ll
= (int) ll
; break;
934 case 64: type
= "quad"; break;
935 default: type
= NULL
; break;
938 assert(type
!= NULL
);
940 printf("\t.%s\t%Ld\n", type
, ll
);
943 static void emit_global_noinit(const char *name
, unsigned long modifiers
,
944 unsigned long alignment
, unsigned int byte_size
)
948 if (modifiers
& MOD_STATIC
) {
949 sprintf(s
, "\t.local\t%s\n", name
);
950 textbuf_push(&unit_post_text
, s
);
953 sprintf(s
, "\t.comm\t%s,%d,%lu\n", name
, byte_size
, alignment
);
955 sprintf(s
, "\t.comm\t%s,%d\n", name
, byte_size
);
956 textbuf_push(&unit_post_text
, s
);
959 static int ea_current
, ea_last
;
961 static void emit_initializer(struct symbol
*sym
,
962 struct expression
*expr
)
964 int distance
= ea_current
- ea_last
- 1;
967 printf("\t.zero\t%d\n", (sym
->bit_size
/ 8) * distance
);
969 if (expr
->type
== EXPR_VALUE
) {
970 struct symbol
*base_type
= sym
->ctype
.base_type
;
971 assert(base_type
!= NULL
);
973 emit_scalar(expr
, sym
->bit_size
/ get_expression_value(base_type
->array_size
));
976 if (expr
->type
!= EXPR_INITIALIZER
)
979 assert(0); /* FIXME */
982 static int sort_array_cmp(const struct expression
*a
,
983 const struct expression
*b
)
985 int a_ofs
= 0, b_ofs
= 0;
987 if (a
->type
== EXPR_POS
)
988 a_ofs
= (int) a
->init_offset
;
989 if (b
->type
== EXPR_POS
)
990 b_ofs
= (int) b
->init_offset
;
992 return a_ofs
- b_ofs
;
995 /* move to front-end? */
996 static void sort_array(struct expression
*expr
)
998 struct expression
*entry
, **list
;
999 unsigned int elem
, sorted
, i
;
1001 elem
= expression_list_size(expr
->expr_list
);
1005 list
= malloc(sizeof(entry
) * elem
);
1007 die("OOM in sort_array");
1009 /* this code is no doubt evil and ignores EXPR_INDEX possibly
1010 * to its detriment and other nasty things. improvements
1015 FOR_EACH_PTR(expr
->expr_list
, entry
) {
1016 if ((entry
->type
== EXPR_POS
) || (entry
->type
== EXPR_VALUE
)) {
1017 /* add entry to list[], in sorted order */
1022 for (i
= 0; i
< sorted
; i
++)
1023 if (sort_array_cmp(entry
, list
[i
]) <= 0)
1026 /* If inserting into the middle of list[]
1027 * instead of appending, we memmove.
1028 * This is ugly, but thankfully
1029 * uncommon. Input data with tons of
1030 * entries very rarely have explicit
1031 * offsets. convert to qsort eventually...
1034 memmove(&list
[i
+ 1], &list
[i
],
1035 (sorted
- i
) * sizeof(entry
));
1040 } END_FOR_EACH_PTR(entry
);
1043 FOR_EACH_PTR(expr
->expr_list
, entry
) {
1044 if ((entry
->type
== EXPR_POS
) || (entry
->type
== EXPR_VALUE
))
1045 *THIS_ADDRESS(entry
) = list
[i
++];
1046 } END_FOR_EACH_PTR(entry
);
1051 static void emit_array(struct symbol
*sym
)
1053 struct symbol
*base_type
= sym
->ctype
.base_type
;
1054 struct expression
*expr
= sym
->initializer
;
1055 struct expression
*entry
;
1057 assert(base_type
!= NULL
);
1063 emit_object_pre(show_ident(sym
->ident
), sym
->ctype
.modifiers
,
1064 sym
->ctype
.alignment
,
1069 FOR_EACH_PTR(expr
->expr_list
, entry
) {
1070 if (entry
->type
== EXPR_VALUE
) {
1072 emit_initializer(sym
, entry
);
1073 ea_last
= ea_current
;
1074 } else if (entry
->type
== EXPR_POS
) {
1076 entry
->init_offset
/ (base_type
->bit_size
/ 8);
1077 emit_initializer(sym
, entry
->init_expr
);
1078 ea_last
= ea_current
;
1080 } END_FOR_EACH_PTR(entry
);
1083 void emit_one_symbol(struct symbol
*sym
)
1088 static void emit_copy(struct storage
*dest
, struct storage
*src
,
1089 struct symbol
*ctype
)
1091 struct storage
*reg
= NULL
;
1092 unsigned int bit_size
;
1094 /* FIXME: Bitfield copy! */
1096 bit_size
= src
->size
* 8;
1099 if ((src
->type
== STOR_ARG
) && (bit_size
< 32))
1102 reg
= temp_from_bits(bit_size
);
1103 emit_move(src
, reg
, ctype
, "begin copy ..");
1105 bit_size
= dest
->size
* 8;
1108 if ((dest
->type
== STOR_ARG
) && (bit_size
< 32))
1111 emit_move(reg
, dest
, ctype
, ".... end copy");
1115 static void emit_store(struct expression
*dest_expr
, struct storage
*dest
,
1116 struct storage
*src
, int bits
)
1118 /* FIXME: Bitfield store! */
1119 printf("\tst.%d\t\tv%d,[v%d]\n", bits
, src
->pseudo
, dest
->pseudo
);
1122 static void emit_scalar_noinit(struct symbol
*sym
)
1124 emit_global_noinit(show_ident(sym
->ident
),
1125 sym
->ctype
.modifiers
, sym
->ctype
.alignment
,
1130 static void emit_array_noinit(struct symbol
*sym
)
1132 emit_global_noinit(show_ident(sym
->ident
),
1133 sym
->ctype
.modifiers
, sym
->ctype
.alignment
,
1134 get_expression_value(sym
->array_size
) * (sym
->bit_size
/ 8));
1138 static const char *opbits(const char *insn
, unsigned int bits
)
1140 static char opbits_str
[32];
1144 case 8: c
= 'b'; break;
1145 case 16: c
= 'w'; break;
1146 case 32: c
= 'l'; break;
1147 case 64: c
= 'q'; break;
1148 default: abort(); break;
1151 sprintf(opbits_str
, "%s%c", insn
, c
);
1156 static void emit_move(struct storage
*src
, struct storage
*dest
,
1157 struct symbol
*ctype
, const char *comment
)
1160 unsigned int is_signed
;
1161 unsigned int is_dest
= (src
->type
== STOR_REG
);
1165 bits
= ctype
->bit_size
;
1166 is_signed
= type_is_signed(ctype
);
1173 * Are we moving from a register to a register?
1174 * Make the new reg to be the "cache".
1176 if ((dest
->type
== STOR_REG
) && (src
->type
== STOR_REG
)) {
1177 struct storage
*backing
;
1183 backing
= src
->reg
->contains
;
1185 /* Is it still valid? */
1186 if (backing
->reg
!= src
->reg
)
1189 backing
->reg
= dest
->reg
;
1191 dest
->reg
->contains
= backing
;
1192 insn("mov", src
, dest
, NULL
);
1197 * Are we moving to a register from a non-reg?
1199 * See if we have the non-reg source already cached
1202 if (dest
->type
== STOR_REG
) {
1204 struct reg_info
*info
= src
->reg
;
1205 if (info
->contains
== src
) {
1206 src
= reginfo_reg(info
);
1210 dest
->reg
->contains
= src
;
1211 src
->reg
= dest
->reg
;
1214 if (src
->type
== STOR_REG
) {
1215 /* We could just mark the register dirty here and do lazy store.. */
1216 src
->reg
->contains
= dest
;
1217 dest
->reg
= src
->reg
;
1220 if ((bits
== 8) || (bits
== 16)) {
1224 opname
= is_signed
? "movsx" : "movzx";
1228 insn(opbits(opname
, bits
), src
, dest
, comment
);
1231 static struct storage
*emit_compare(struct expression
*expr
)
1233 struct storage
*left
= x86_expression(expr
->left
);
1234 struct storage
*right
= x86_expression(expr
->right
);
1235 struct storage
*reg1
, *reg2
;
1236 struct storage
*new, *val
;
1237 const char *opname
= NULL
;
1238 unsigned int right_bits
= expr
->right
->ctype
->bit_size
;
1241 case '<': opname
= "setl"; break;
1242 case '>': opname
= "setg"; break;
1244 opname
= "setle"; break;
1246 opname
= "setge"; break;
1247 case SPECIAL_EQUAL
: opname
= "sete"; break;
1248 case SPECIAL_NOTEQUAL
: opname
= "setne"; break;
1249 case SPECIAL_UNSIGNED_LT
:
1250 opname
= "setb"; break;
1251 case SPECIAL_UNSIGNED_GT
:
1252 opname
= "seta"; break;
1253 case SPECIAL_UNSIGNED_LTE
:
1254 opname
= "setb"; break;
1255 case SPECIAL_UNSIGNED_GTE
:
1256 opname
= "setae"; break;
1263 val
= new_storage(STOR_VALUE
);
1264 val
->flags
= STOR_WANTS_FREE
;
1266 reg1
= get_reg(®class_32_8
);
1267 emit_move(val
, reg1
, NULL
, NULL
);
1269 /* move op1 into EAX */
1270 reg2
= get_reg_value(left
, get_regclass(expr
->left
));
1272 /* perform comparison, RHS (op1, right) and LHS (op2, EAX) */
1273 insn(opbits("cmp", right_bits
), right
, reg2
, NULL
);
1276 /* store result of operation, 0 or 1, in DL using SETcc */
1277 insn(opname
, byte_reg(reg1
), NULL
, NULL
);
1279 /* finally, store the result (DL) in a new pseudo / stack slot */
1280 new = stack_alloc(4);
1281 emit_move(reg1
, new, NULL
, "end EXPR_COMPARE");
1287 static struct storage
*emit_value(struct expression
*expr
)
1289 #if 0 /* old and slow way */
1290 struct storage
*new = stack_alloc(4);
1291 struct storage
*val
;
1293 val
= new_storage(STOR_VALUE
);
1294 val
->value
= (long long) expr
->value
;
1295 val
->flags
= STOR_WANTS_FREE
;
1296 insn("movl", val
, new, NULL
);
1300 struct storage
*val
;
1302 val
= new_storage(STOR_VALUE
);
1303 val
->value
= (long long) expr
->value
;
1305 return val
; /* FIXME: memory leak */
1309 static struct storage
*emit_divide(struct expression
*expr
, struct storage
*left
, struct storage
*right
)
1311 struct storage
*eax_edx
;
1312 struct storage
*reg
, *new;
1313 struct storage
*val
= new_storage(STOR_VALUE
);
1315 emit_comment("begin DIVIDE");
1316 eax_edx
= get_hardreg(hardreg_storage_table
+ EAX_EDX
, 1);
1319 val
->flags
= STOR_WANTS_FREE
;
1320 emit_move(val
, REG_EDX
, NULL
, NULL
);
1322 new = stack_alloc(expr
->ctype
->bit_size
/ 8);
1324 /* EAX is dividend */
1325 emit_move(left
, REG_EAX
, NULL
, NULL
);
1327 reg
= get_reg_value(right
, ®class_32
);
1330 insn("div", reg
, REG_EAX
, NULL
);
1334 if (expr
->op
== '%')
1336 emit_move(reg
, new, NULL
, NULL
);
1339 emit_comment("end DIVIDE");
1343 static struct storage
*emit_binop(struct expression
*expr
)
1345 struct storage
*left
= x86_expression(expr
->left
);
1346 struct storage
*right
= x86_expression(expr
->right
);
1347 struct storage
*new;
1348 struct storage
*dest
, *src
;
1349 const char *opname
= NULL
;
1350 const char *suffix
= NULL
;
1354 /* Divides have special register constraints */
1355 if ((expr
->op
== '/') || (expr
->op
== '%'))
1356 return emit_divide(expr
, left
, right
);
1358 is_signed
= type_is_signed(expr
->ctype
);
1376 case SPECIAL_LEFTSHIFT
:
1379 case SPECIAL_RIGHTSHIFT
:
1391 case SPECIAL_LOGICAL_AND
:
1392 warning(expr
->pos
, "bogus bitwise and for logical op (should use '2*setne + and' or something)");
1395 case SPECIAL_LOGICAL_OR
:
1396 warning(expr
->pos
, "bogus bitwise or for logical op (should use 'or + setne' or something)");
1400 error_die(expr
->pos
, "unhandled binop '%s'\n", show_special(expr
->op
));
1404 dest
= get_reg_value(right
, ®class_32
);
1405 src
= get_reg_value(left
, ®class_32
);
1406 switch (expr
->ctype
->bit_size
) {
1417 suffix
= "q"; /* FIXME */
1424 snprintf(opstr
, sizeof(opstr
), "%s%s", opname
, suffix
);
1427 insn(opstr
, src
, dest
, NULL
);
1430 /* store result in new pseudo / stack slot */
1431 new = stack_alloc(expr
->ctype
->bit_size
/ 8);
1432 emit_move(dest
, new, NULL
, "end EXPR_BINOP");
1439 static int emit_conditional_test(struct storage
*val
)
1441 struct storage
*reg
;
1442 struct storage
*target_val
;
1445 /* load result into EAX */
1446 emit_comment("begin if/conditional");
1447 reg
= get_reg_value(val
, ®class_32
);
1449 /* compare result with zero */
1450 insn("test", reg
, reg
, NULL
);
1453 /* create conditional-failed label to jump to */
1454 target_false
= new_label();
1455 target_val
= new_storage(STOR_LABEL
);
1456 target_val
->label
= target_false
;
1457 target_val
->flags
= STOR_WANTS_FREE
;
1458 insn("jz", target_val
, NULL
, NULL
);
1460 return target_false
;
1463 static int emit_conditional_end(int target_false
)
1465 struct storage
*cond_end_st
;
1468 /* finished generating code for if-true statement.
1469 * add a jump-to-end jump to avoid falling through
1470 * to the if-false statement code.
1472 cond_end
= new_label();
1473 cond_end_st
= new_storage(STOR_LABEL
);
1474 cond_end_st
->label
= cond_end
;
1475 cond_end_st
->flags
= STOR_WANTS_FREE
;
1476 insn("jmp", cond_end_st
, NULL
, NULL
);
1478 /* if we have both if-true and if-false statements,
1479 * the failed-conditional case will fall through to here
1481 emit_label(target_false
, NULL
);
1486 static void emit_if_conditional(struct statement
*stmt
)
1488 struct storage
*val
;
1491 /* emit test portion of conditional */
1492 val
= x86_expression(stmt
->if_conditional
);
1493 cond_end
= emit_conditional_test(val
);
1495 /* emit if-true statement */
1496 x86_statement(stmt
->if_true
);
1498 /* emit if-false statement, if present */
1499 if (stmt
->if_false
) {
1500 cond_end
= emit_conditional_end(cond_end
);
1501 x86_statement(stmt
->if_false
);
1504 /* end of conditional; jump target for if-true branch */
1505 emit_label(cond_end
, "end if");
1508 static struct storage
*emit_inc_dec(struct expression
*expr
, int postop
)
1510 struct storage
*addr
= x86_address_gen(expr
->unop
);
1511 struct storage
*retval
;
1514 strcpy(opname
, opbits(expr
->op
== SPECIAL_INCREMENT
? "inc" : "dec",
1515 expr
->ctype
->bit_size
));
1518 struct storage
*new = stack_alloc(4);
1520 emit_copy(new, addr
, expr
->unop
->ctype
);
1526 insn(opname
, addr
, NULL
, NULL
);
1531 static struct storage
*emit_postop(struct expression
*expr
)
1533 return emit_inc_dec(expr
, 1);
1536 static struct storage
*emit_return_stmt(struct statement
*stmt
)
1538 struct function
*f
= current_func
;
1539 struct expression
*expr
= stmt
->ret_value
;
1540 struct storage
*val
= NULL
, *jmplbl
;
1542 if (expr
&& expr
->ctype
) {
1543 val
= x86_expression(expr
);
1544 assert(val
!= NULL
);
1545 emit_move(val
, REG_EAX
, expr
->ctype
, "return");
1548 jmplbl
= new_storage(STOR_LABEL
);
1549 jmplbl
->flags
|= STOR_WANTS_FREE
;
1550 jmplbl
->label
= f
->ret_target
;
1551 insn("jmp", jmplbl
, NULL
, NULL
);
1556 static struct storage
*emit_conditional_expr(struct expression
*expr
)
1558 struct storage
*cond
, *true = NULL
, *false = NULL
;
1559 struct storage
*new = stack_alloc(expr
->ctype
->bit_size
/ 8);
1560 int target_false
, cond_end
;
1562 /* evaluate conditional */
1563 cond
= x86_expression(expr
->conditional
);
1564 target_false
= emit_conditional_test(cond
);
1566 /* handle if-true part of the expression */
1567 true = x86_expression(expr
->cond_true
);
1569 emit_copy(new, true, expr
->ctype
);
1571 cond_end
= emit_conditional_end(target_false
);
1573 /* handle if-false part of the expression */
1574 false = x86_expression(expr
->cond_false
);
1576 emit_copy(new, false, expr
->ctype
);
1578 /* end of conditional; jump target for if-true branch */
1579 emit_label(cond_end
, "end conditional");
1584 static struct storage
*emit_select_expr(struct expression
*expr
)
1586 struct storage
*cond
= x86_expression(expr
->conditional
);
1587 struct storage
*true = x86_expression(expr
->cond_true
);
1588 struct storage
*false = x86_expression(expr
->cond_false
);
1589 struct storage
*reg_cond
, *reg_true
, *reg_false
;
1590 struct storage
*new = stack_alloc(4);
1592 emit_comment("begin SELECT");
1593 reg_cond
= get_reg_value(cond
, get_regclass(expr
->conditional
));
1594 reg_true
= get_reg_value(true, get_regclass(expr
));
1595 reg_false
= get_reg_value(false, get_regclass(expr
));
1598 * Do the actual select: check the conditional for zero,
1599 * move false over true if zero
1601 insn("test", reg_cond
, reg_cond
, NULL
);
1602 insn("cmovz", reg_false
, reg_true
, NULL
);
1605 emit_move(reg_true
, new, expr
->ctype
, NULL
);
1609 emit_comment("end SELECT");
1613 static struct storage
*emit_symbol_expr_init(struct symbol
*sym
)
1615 struct expression
*expr
= sym
->initializer
;
1616 struct symbol_private
*priv
= sym
->aux
;
1619 priv
= calloc(1, sizeof(*priv
));
1623 struct storage
*new = stack_alloc(4);
1624 fprintf(stderr
, "FIXME! no value for symbol %s. creating pseudo %d (stack offset %d)\n",
1625 show_ident(sym
->ident
),
1626 new->pseudo
, new->pseudo
* 4);
1629 priv
->addr
= x86_expression(expr
);
1636 static struct storage
*emit_string_expr(struct expression
*expr
)
1638 struct function
*f
= current_func
;
1639 int label
= new_label();
1640 struct storage
*new;
1642 push_cstring(f
, expr
->string
, label
);
1644 new = new_storage(STOR_LABEL
);
1646 new->flags
= STOR_LABEL_VAL
| STOR_WANTS_FREE
;
1650 static struct storage
*emit_cast_expr(struct expression
*expr
)
1652 struct symbol
*old_type
, *new_type
;
1653 struct storage
*op
= x86_expression(expr
->cast_expression
);
1654 int oldbits
, newbits
;
1655 struct storage
*new;
1657 old_type
= expr
->cast_expression
->ctype
;
1658 new_type
= expr
->cast_type
;
1660 oldbits
= old_type
->bit_size
;
1661 newbits
= new_type
->bit_size
;
1662 if (oldbits
>= newbits
)
1665 emit_move(op
, REG_EAX
, old_type
, "begin cast ..");
1667 new = stack_alloc(newbits
/ 8);
1668 emit_move(REG_EAX
, new, new_type
, ".... end cast");
1673 static struct storage
*emit_regular_preop(struct expression
*expr
)
1675 struct storage
*target
= x86_expression(expr
->unop
);
1676 struct storage
*val
, *new = stack_alloc(4);
1677 const char *opname
= NULL
;
1681 val
= new_storage(STOR_VALUE
);
1682 val
->flags
= STOR_WANTS_FREE
;
1683 emit_move(val
, REG_EDX
, NULL
, NULL
);
1684 emit_move(target
, REG_EAX
, expr
->unop
->ctype
, NULL
);
1685 insn("test", REG_EAX
, REG_EAX
, NULL
);
1686 insn("setz", REG_DL
, NULL
, NULL
);
1687 emit_move(REG_EDX
, new, expr
->unop
->ctype
, NULL
);
1695 emit_move(target
, REG_EAX
, expr
->unop
->ctype
, NULL
);
1696 insn(opname
, REG_EAX
, NULL
, NULL
);
1697 emit_move(REG_EAX
, new, expr
->unop
->ctype
, NULL
);
1707 static void emit_case_statement(struct statement
*stmt
)
1709 emit_labelsym(stmt
->case_label
, NULL
);
1710 x86_statement(stmt
->case_statement
);
1713 static void emit_switch_statement(struct statement
*stmt
)
1715 struct storage
*val
= x86_expression(stmt
->switch_expression
);
1716 struct symbol
*sym
, *default_sym
= NULL
;
1717 struct storage
*labelsym
, *label
;
1720 emit_move(val
, REG_EAX
, stmt
->switch_expression
->ctype
, "begin case");
1723 * This is where a _real_ back-end would go through the
1724 * cases to decide whether to use a lookup table or a
1725 * series of comparisons etc
1727 FOR_EACH_PTR(stmt
->switch_case
->symbol_list
, sym
) {
1728 struct statement
*case_stmt
= sym
->stmt
;
1729 struct expression
*expr
= case_stmt
->case_expression
;
1730 struct expression
*to
= case_stmt
->case_to
;
1738 struct storage
*case_val
= new_val(expr
->value
);
1740 assert (expr
->type
== EXPR_VALUE
);
1742 insn("cmpl", case_val
, REG_EAX
, NULL
);
1745 labelsym
= new_labelsym(sym
);
1746 insn("je", labelsym
, NULL
, NULL
);
1750 label
= new_storage(STOR_LABEL
);
1751 label
->flags
|= STOR_WANTS_FREE
;
1752 label
->label
= next_test
= new_label();
1754 /* FIXME: signed/unsigned */
1755 insn("jl", label
, NULL
, NULL
);
1757 case_val
= new_val(to
->value
);
1758 insn("cmpl", case_val
, REG_EAX
, NULL
);
1760 /* TODO: implement and use refcounting... */
1761 label
= new_storage(STOR_LABEL
);
1762 label
->flags
|= STOR_WANTS_FREE
;
1763 label
->label
= next_test
;
1765 /* FIXME: signed/unsigned */
1766 insn("jg", label
, NULL
, NULL
);
1768 labelsym
= new_labelsym(sym
);
1769 insn("jmp", labelsym
, NULL
, NULL
);
1771 emit_label(next_test
, NULL
);
1774 } END_FOR_EACH_PTR(sym
);
1777 labelsym
= new_labelsym(default_sym
);
1778 insn("jmp", labelsym
, NULL
, "default");
1780 label
= new_storage(STOR_LABEL
);
1781 label
->flags
|= STOR_WANTS_FREE
;
1782 label
->label
= switch_end
= new_label();
1783 insn("jmp", label
, NULL
, "goto end of switch");
1786 x86_statement(stmt
->switch_statement
);
1788 if (stmt
->switch_break
->used
)
1789 emit_labelsym(stmt
->switch_break
, NULL
);
1792 emit_label(switch_end
, NULL
);
1795 static void x86_struct_member(struct symbol
*sym
)
1797 printf("\t%s:%d:%ld at offset %ld.%d", show_ident(sym
->ident
), sym
->bit_size
, sym
->ctype
.alignment
, sym
->offset
, sym
->bit_offset
);
1801 static void x86_symbol(struct symbol
*sym
)
1803 struct symbol
*type
;
1808 type
= sym
->ctype
.base_type
;
1813 * Show actual implementation information
1815 switch (type
->type
) {
1818 if (sym
->initializer
)
1821 emit_array_noinit(sym
);
1825 if (sym
->initializer
) {
1826 emit_object_pre(show_ident(sym
->ident
),
1827 sym
->ctype
.modifiers
,
1828 sym
->ctype
.alignment
,
1830 emit_scalar(sym
->initializer
, sym
->bit_size
);
1833 emit_scalar_noinit(sym
);
1838 struct symbol
*member
;
1841 FOR_EACH_PTR(type
->symbol_list
, member
) {
1842 x86_struct_member(member
);
1843 } END_FOR_EACH_PTR(member
);
1849 struct statement
*stmt
= type
->stmt
;
1852 x86_statement(stmt
);
1853 emit_func_post(sym
);
1862 if (sym
->initializer
&& (type
->type
!= SYM_BASETYPE
) &&
1863 (type
->type
!= SYM_ARRAY
)) {
1865 x86_expression(sym
->initializer
);
1869 static void x86_symbol_init(struct symbol
*sym
);
1871 static void x86_symbol_decl(struct symbol_list
*syms
)
1874 FOR_EACH_PTR(syms
, sym
) {
1875 x86_symbol_init(sym
);
1876 } END_FOR_EACH_PTR(sym
);
1879 static void loopstk_push(int cont_lbl
, int loop_bottom_lbl
)
1881 struct function
*f
= current_func
;
1882 struct loop_stack
*ls
;
1884 ls
= malloc(sizeof(*ls
));
1885 ls
->continue_lbl
= cont_lbl
;
1886 ls
->loop_bottom_lbl
= loop_bottom_lbl
;
1887 ls
->next
= f
->loop_stack
;
1891 static void loopstk_pop(void)
1893 struct function
*f
= current_func
;
1894 struct loop_stack
*ls
;
1896 assert(f
->loop_stack
!= NULL
);
1898 f
->loop_stack
= f
->loop_stack
->next
;
1902 static int loopstk_break(void)
1904 return current_func
->loop_stack
->loop_bottom_lbl
;
1907 static int loopstk_continue(void)
1909 return current_func
->loop_stack
->continue_lbl
;
1912 static void emit_loop(struct statement
*stmt
)
1914 struct statement
*pre_statement
= stmt
->iterator_pre_statement
;
1915 struct expression
*pre_condition
= stmt
->iterator_pre_condition
;
1916 struct statement
*statement
= stmt
->iterator_statement
;
1917 struct statement
*post_statement
= stmt
->iterator_post_statement
;
1918 struct expression
*post_condition
= stmt
->iterator_post_condition
;
1919 int loop_top
= 0, loop_bottom
, loop_continue
;
1920 int have_bottom
= 0;
1921 struct storage
*val
;
1923 loop_bottom
= new_label();
1924 loop_continue
= new_label();
1925 loopstk_push(loop_continue
, loop_bottom
);
1927 x86_symbol_decl(stmt
->iterator_syms
);
1928 x86_statement(pre_statement
);
1929 if (!post_condition
|| post_condition
->type
!= EXPR_VALUE
|| post_condition
->value
) {
1930 loop_top
= new_label();
1931 emit_label(loop_top
, "loop top");
1933 if (pre_condition
) {
1934 if (pre_condition
->type
== EXPR_VALUE
) {
1935 if (!pre_condition
->value
) {
1936 struct storage
*lbv
;
1937 lbv
= new_storage(STOR_LABEL
);
1938 lbv
->label
= loop_bottom
;
1939 lbv
->flags
= STOR_WANTS_FREE
;
1940 insn("jmp", lbv
, NULL
, "go to loop bottom");
1944 struct storage
*lbv
= new_storage(STOR_LABEL
);
1945 lbv
->label
= loop_bottom
;
1946 lbv
->flags
= STOR_WANTS_FREE
;
1949 val
= x86_expression(pre_condition
);
1951 emit_move(val
, REG_EAX
, NULL
, "loop pre condition");
1952 insn("test", REG_EAX
, REG_EAX
, NULL
);
1953 insn("jz", lbv
, NULL
, NULL
);
1956 x86_statement(statement
);
1957 if (stmt
->iterator_continue
->used
)
1958 emit_label(loop_continue
, "'continue' iterator");
1959 x86_statement(post_statement
);
1960 if (!post_condition
) {
1961 struct storage
*lbv
= new_storage(STOR_LABEL
);
1962 lbv
->label
= loop_top
;
1963 lbv
->flags
= STOR_WANTS_FREE
;
1964 insn("jmp", lbv
, NULL
, "go to loop top");
1965 } else if (post_condition
->type
== EXPR_VALUE
) {
1966 if (post_condition
->value
) {
1967 struct storage
*lbv
= new_storage(STOR_LABEL
);
1968 lbv
->label
= loop_top
;
1969 lbv
->flags
= STOR_WANTS_FREE
;
1970 insn("jmp", lbv
, NULL
, "go to loop top");
1973 struct storage
*lbv
= new_storage(STOR_LABEL
);
1974 lbv
->label
= loop_top
;
1975 lbv
->flags
= STOR_WANTS_FREE
;
1977 val
= x86_expression(post_condition
);
1979 emit_move(val
, REG_EAX
, NULL
, "loop post condition");
1980 insn("test", REG_EAX
, REG_EAX
, NULL
);
1981 insn("jnz", lbv
, NULL
, NULL
);
1983 if (have_bottom
|| stmt
->iterator_break
->used
)
1984 emit_label(loop_bottom
, "loop bottom");
1990 * Print out a statement
1992 static struct storage
*x86_statement(struct statement
*stmt
)
1996 switch (stmt
->type
) {
2000 return emit_return_stmt(stmt
);
2001 case STMT_DECLARATION
:
2002 x86_symbol_decl(stmt
->declaration
);
2004 case STMT_COMPOUND
: {
2005 struct statement
*s
;
2006 struct storage
*last
= NULL
;
2008 FOR_EACH_PTR(stmt
->stmts
, s
) {
2009 last
= x86_statement(s
);
2010 } END_FOR_EACH_PTR(s
);
2015 case STMT_EXPRESSION
:
2016 return x86_expression(stmt
->expression
);
2018 emit_if_conditional(stmt
);
2022 emit_case_statement(stmt
);
2025 emit_switch_statement(stmt
);
2036 printf(".L%p:\n", stmt
->label_identifier
);
2037 x86_statement(stmt
->label_statement
);
2041 if (stmt
->goto_expression
) {
2042 struct storage
*val
= x86_expression(stmt
->goto_expression
);
2043 printf("\tgoto *v%d\n", val
->pseudo
);
2044 } else if (!strcmp("break", show_ident(stmt
->goto_label
->ident
))) {
2045 struct storage
*lbv
= new_storage(STOR_LABEL
);
2046 lbv
->label
= loopstk_break();
2047 lbv
->flags
= STOR_WANTS_FREE
;
2048 insn("jmp", lbv
, NULL
, "'break'; go to loop bottom");
2049 } else if (!strcmp("continue", show_ident(stmt
->goto_label
->ident
))) {
2050 struct storage
*lbv
= new_storage(STOR_LABEL
);
2051 lbv
->label
= loopstk_continue();
2052 lbv
->flags
= STOR_WANTS_FREE
;
2053 insn("jmp", lbv
, NULL
, "'continue'; go to loop top");
2055 struct storage
*labelsym
= new_labelsym(stmt
->goto_label
);
2056 insn("jmp", labelsym
, NULL
, NULL
);
2060 printf("\tasm( .... )\n");
2066 static struct storage
*x86_call_expression(struct expression
*expr
)
2068 struct function
*f
= current_func
;
2069 struct symbol
*direct
;
2070 struct expression
*arg
, *fn
;
2071 struct storage
*retval
, *fncall
;
2076 warning(expr
->pos
, "\tcall with no type!");
2081 FOR_EACH_PTR_REVERSE(expr
->args
, arg
) {
2082 struct storage
*new = x86_expression(arg
);
2083 int size
= arg
->ctype
->bit_size
;
2086 * FIXME: i386 SysV ABI dictates that values
2087 * smaller than 32 bits should be placed onto
2088 * the stack as 32-bit objects. We should not
2089 * blindly do a 32-bit push on objects smaller
2094 insn("pushl", new, NULL
,
2095 !framesize
? "begin function call" : NULL
);
2097 framesize
+= bits_to_bytes(size
);
2098 } END_FOR_EACH_PTR_REVERSE(arg
);
2102 /* Remove dereference, if any */
2104 if (fn
->type
== EXPR_PREOP
) {
2105 if (fn
->unop
->type
== EXPR_SYMBOL
) {
2106 struct symbol
*sym
= fn
->unop
->symbol
;
2107 if (sym
->ctype
.base_type
->type
== SYM_FN
)
2112 struct storage
*direct_stor
= new_storage(STOR_SYM
);
2113 direct_stor
->flags
|= STOR_WANTS_FREE
;
2114 direct_stor
->sym
= direct
;
2115 insn("call", direct_stor
, NULL
, NULL
);
2117 fncall
= x86_expression(fn
);
2118 emit_move(fncall
, REG_EAX
, fn
->ctype
, NULL
);
2120 strcpy(s
, "\tcall\t*%eax\n");
2121 push_text_atom(f
, s
);
2124 /* FIXME: pay attention to BITS_IN_POINTER */
2126 struct storage
*val
= new_storage(STOR_VALUE
);
2127 val
->value
= (long long) framesize
;
2128 val
->flags
= STOR_WANTS_FREE
;
2129 insn("addl", val
, REG_ESP
, NULL
);
2132 retval
= stack_alloc(4);
2133 emit_move(REG_EAX
, retval
, NULL
, "end function call");
2138 static struct storage
*x86_address_gen(struct expression
*expr
)
2140 struct function
*f
= current_func
;
2141 struct storage
*addr
;
2142 struct storage
*new;
2145 addr
= x86_expression(expr
->unop
);
2146 if (expr
->unop
->type
== EXPR_SYMBOL
)
2149 emit_move(addr
, REG_EAX
, NULL
, "begin deref ..");
2151 /* FIXME: operand size */
2152 strcpy(s
, "\tmovl\t(%eax), %ecx\n");
2153 push_text_atom(f
, s
);
2155 new = stack_alloc(4);
2156 emit_move(REG_ECX
, new, NULL
, ".... end deref");
2161 static struct storage
*x86_assignment(struct expression
*expr
)
2163 struct expression
*target
= expr
->left
;
2164 struct storage
*val
, *addr
;
2169 val
= x86_expression(expr
->right
);
2170 addr
= x86_address_gen(target
);
2172 switch (val
->type
) {
2173 /* copy, where both operands are memory */
2176 emit_copy(addr
, val
, expr
->ctype
);
2179 /* copy, one or zero operands are memory */
2184 emit_move(val
, addr
, expr
->left
->ctype
, NULL
);
2194 static int x86_initialization(struct symbol
*sym
, struct expression
*expr
)
2196 struct storage
*val
, *addr
;
2202 bits
= expr
->ctype
->bit_size
;
2203 val
= x86_expression(expr
);
2204 addr
= x86_symbol_expr(sym
);
2205 // FIXME! The "target" expression is for bitfield store information.
2206 // Leave it NULL, which works fine.
2207 emit_store(NULL
, addr
, val
, bits
);
2211 static struct storage
*x86_access(struct expression
*expr
)
2213 return x86_address_gen(expr
);
2216 static struct storage
*x86_preop(struct expression
*expr
)
2219 * '*' is an lvalue access, and is fundamentally different
2220 * from an arithmetic operation. Maybe it should have an
2221 * expression type of its own..
2223 if (expr
->op
== '*')
2224 return x86_access(expr
);
2225 if (expr
->op
== SPECIAL_INCREMENT
|| expr
->op
== SPECIAL_DECREMENT
)
2226 return emit_inc_dec(expr
, 0);
2227 return emit_regular_preop(expr
);
2230 static struct storage
*x86_symbol_expr(struct symbol
*sym
)
2232 struct storage
*new = stack_alloc(4);
2234 if (sym
->ctype
.modifiers
& (MOD_TOPLEVEL
| MOD_EXTERN
| MOD_STATIC
)) {
2235 printf("\tmovi.%d\t\tv%d,$%s\n", bits_in_pointer
, new->pseudo
, show_ident(sym
->ident
));
2238 if (sym
->ctype
.modifiers
& MOD_ADDRESSABLE
) {
2239 printf("\taddi.%d\t\tv%d,vFP,$%lld\n", bits_in_pointer
, new->pseudo
, sym
->value
);
2242 printf("\taddi.%d\t\tv%d,vFP,$offsetof(%s:%p)\n", bits_in_pointer
, new->pseudo
, show_ident(sym
->ident
), sym
);
2246 static void x86_symbol_init(struct symbol
*sym
)
2248 struct symbol_private
*priv
= sym
->aux
;
2249 struct expression
*expr
= sym
->initializer
;
2250 struct storage
*new;
2253 new = x86_expression(expr
);
2255 new = stack_alloc(sym
->bit_size
/ 8);
2258 priv
= calloc(1, sizeof(*priv
));
2260 /* FIXME: leak! we don't free... */
2261 /* (well, we don't free symbols either) */
2267 static int type_is_signed(struct symbol
*sym
)
2269 if (sym
->type
== SYM_NODE
)
2270 sym
= sym
->ctype
.base_type
;
2271 if (sym
->type
== SYM_PTR
)
2273 return !(sym
->ctype
.modifiers
& MOD_UNSIGNED
);
2276 static struct storage
*x86_label_expr(struct expression
*expr
)
2278 struct storage
*new = stack_alloc(4);
2279 printf("\tmovi.%d\t\tv%d,.L%p\n", bits_in_pointer
, new->pseudo
, expr
->label_symbol
);
2283 static struct storage
*x86_statement_expr(struct expression
*expr
)
2285 return x86_statement(expr
->statement
);
2288 static int x86_position_expr(struct expression
*expr
, struct symbol
*base
)
2290 struct storage
*new = x86_expression(expr
->init_expr
);
2291 struct symbol
*ctype
= expr
->init_expr
->ctype
;
2293 printf("\tinsert v%d at [%d:%d] of %s\n", new->pseudo
,
2294 expr
->init_offset
, ctype
->bit_offset
,
2295 show_ident(base
->ident
));
2299 static void x86_initializer_expr(struct expression
*expr
, struct symbol
*ctype
)
2301 struct expression
*entry
;
2303 FOR_EACH_PTR(expr
->expr_list
, entry
) {
2304 // Nested initializers have their positions already
2305 // recursively calculated - just output them too
2306 if (entry
->type
== EXPR_INITIALIZER
) {
2307 x86_initializer_expr(entry
, ctype
);
2311 // Ignore initializer indexes and identifiers - the
2312 // evaluator has taken them into account
2313 if (entry
->type
== EXPR_IDENTIFIER
|| entry
->type
== EXPR_INDEX
)
2315 if (entry
->type
== EXPR_POS
) {
2316 x86_position_expr(entry
, ctype
);
2319 x86_initialization(ctype
, entry
);
2320 } END_FOR_EACH_PTR(entry
);
2324 * Print out an expression. Return the pseudo that contains the
2327 static struct storage
*x86_expression(struct expression
*expr
)
2333 struct position
*pos
= &expr
->pos
;
2334 printf("\tno type at %s:%d:%d\n",
2335 stream_name(pos
->stream
),
2336 pos
->line
, pos
->pos
);
2340 switch (expr
->type
) {
2344 return x86_call_expression(expr
);
2346 case EXPR_ASSIGNMENT
:
2347 return x86_assignment(expr
);
2350 return emit_compare(expr
);
2354 return emit_binop(expr
);
2356 return x86_preop(expr
);
2358 return emit_postop(expr
);
2360 return emit_symbol_expr_init(expr
->symbol
);
2364 warning(expr
->pos
, "invalid expression after evaluation");
2367 case EXPR_FORCE_CAST
:
2368 case EXPR_IMPLIED_CAST
:
2369 return emit_cast_expr(expr
);
2371 return emit_value(expr
);
2373 return emit_string_expr(expr
);
2374 case EXPR_INITIALIZER
:
2375 x86_initializer_expr(expr
, expr
->ctype
);
2378 return emit_select_expr(expr
);
2379 case EXPR_CONDITIONAL
:
2380 return emit_conditional_expr(expr
);
2381 case EXPR_STATEMENT
:
2382 return x86_statement_expr(expr
);
2384 return x86_label_expr(expr
);
2386 // None of these should exist as direct expressions: they are only
2387 // valid as sub-expressions of initializers.
2389 warning(expr
->pos
, "unable to show plain initializer position expression");
2391 case EXPR_IDENTIFIER
:
2392 warning(expr
->pos
, "unable to show identifier expression");
2395 warning(expr
->pos
, "unable to show index expression");
2398 warning(expr
->pos
, "unable to show type expression");
2401 warning(expr
->pos
, "floating point support is not implemented");