1/*
2 * sparse/compile-i386.c
3 *
4 * Copyright (C) 2003 Transmeta Corp.
5 *               2003 Linus Torvalds
6 * Copyright 2003 Jeff Garzik
7 *
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:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
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
24 * THE SOFTWARE.
25 *
26 * x86 backend
27 *
28 * TODO list:
29 * in general, any non-32bit SYM_BASETYPE is unlikely to work.
30 * complex initializers
31 * bitfields
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.
35 * labels / goto
36 * any function argument that isn't 32 bits (or promoted to such)
37 * inline asm
38 * floating point
39 *
40 */
41#include <stdarg.h>
42#include <stdlib.h>
43#include <stdio.h>
44#include <string.h>
45#include <ctype.h>
46#include <unistd.h>
47#include <fcntl.h>
48#include <assert.h>
49
50#include "lib.h"
51#include "allocate.h"
52#include "token.h"
53#include "parse.h"
54#include "symbol.h"
55#include "scope.h"
56#include "expression.h"
57#include "target.h"
58#include "compile.h"
59#include "bitmap.h"
60
61struct textbuf {
62	unsigned int	len;	/* does NOT include terminating null */
63	char		*text;
64	struct textbuf	*next;
65	struct textbuf	*prev;
66};
67
68struct loop_stack {
69	int		continue_lbl;
70	int		loop_bottom_lbl;
71	struct loop_stack *next;
72};
73
74struct atom;
75struct storage;
76DECLARE_PTR_LIST(str_list, struct atom);
77DECLARE_PTR_LIST(atom_list, struct atom);
78DECLARE_PTR_LIST(storage_list, struct storage);
79
80struct function {
81	int stack_size;
82	int pseudo_nr;
83	struct storage_list *pseudo_list;
84	struct atom_list *atom_list;
85	struct str_list *str_list;
86	struct loop_stack *loop_stack;
87	struct symbol **argv;
88	unsigned int argc;
89	int ret_target;
90};
91
92enum storage_type {
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 */
100};
101
102struct reg_info {
103	const char	*name;
104	struct storage	*contains;
105	const unsigned char aliases[12];
106#define own_regno aliases[0]
107};
108
109struct storage {
110	enum storage_type type;
111	unsigned long flags;
112
113	/* STOR_REG */
114	struct reg_info *reg;
115	struct symbol *ctype;
116
117	union {
118		/* STOR_PSEUDO */
119		struct {
120			int pseudo;
121			int offset;
122			int size;
123		};
124		/* STOR_ARG */
125		struct {
126			int idx;
127		};
128		/* STOR_SYM */
129		struct {
130			struct symbol *sym;
131		};
132		/* STOR_VALUE */
133		struct {
134			long long value;
135		};
136		/* STOR_LABEL */
137		struct {
138			int label;
139		};
140		/* STOR_LABELSYM */
141		struct {
142			struct symbol *labelsym;
143		};
144	};
145};
146
147enum {
148	STOR_LABEL_VAL	= (1 << 0),
149	STOR_WANTS_FREE	= (1 << 1),
150};
151
152struct symbol_private {
153	struct storage *addr;
154};
155
156enum atom_type {
157	ATOM_TEXT,
158	ATOM_INSN,
159	ATOM_CSTR,
160};
161
162struct atom {
163	enum atom_type type;
164	union {
165		/* stuff for text */
166		struct {
167			char *text;
168			unsigned int text_len;  /* w/o terminating null */
169		};
170
171		/* stuff for insns */
172		struct {
173			char insn[32];
174			char comment[40];
175			struct storage *op1;
176			struct storage *op2;
177		};
178
179		/* stuff for C strings */
180		struct {
181			struct string *string;
182			int label;
183		};
184	};
185};
186
187
188static struct function *current_func = NULL;
189static struct textbuf *unit_post_text = NULL;
190static const char *current_section;
191
192static void emit_comment(const char * fmt, ...) FORMAT_ATTR(1);
193static void emit_move(struct storage *src, struct storage *dest,
194		      struct symbol *ctype, const char *comment);
195static struct storage *x86_address_gen(struct expression *expr);
196static struct storage *x86_symbol_expr(struct symbol *sym);
197static void x86_symbol(struct symbol *sym);
198static struct storage *x86_statement(struct statement *stmt);
199static struct storage *x86_expression(struct expression *expr);
200
201enum registers {
202	NOREG,
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
207};
208
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)
213
214#define REGINFO(nr, str, conflicts...)	[nr] = { .name = str, .aliases = { nr , conflicts } }
215
216static 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),
244};
245
246#define REGSTORAGE(nr) [nr] = { .type = STOR_REG, .reg = reg_info_table + (nr) }
247
248static 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),
256};
257
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])
266
267static DECLARE_BITMAP(regs_in_use, 256);
268
269static inline struct storage * reginfo_reg(struct reg_info *info)
270{
271	return hardreg_storage_table + info->own_regno;
272}
273
274static struct storage * get_hardreg(struct storage *reg, int clear)
275{
276	struct reg_info *info = reg->reg;
277	const unsigned char *aliases;
278	int regno;
279
280	aliases = info->aliases;
281	while ((regno = *aliases++) != NOREG) {
282		if (test_bit(regno, regs_in_use))
283			goto busy;
284		if (clear)
285			reg_info_table[regno].contains = NULL;
286	}
287	set_bit(info->own_regno, regs_in_use);
288	return reg;
289busy:
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);
293	exit(1);
294}
295
296static void put_reg(struct storage *reg)
297{
298	struct reg_info *info = reg->reg;
299	int regno = info->own_regno;
300
301	if (test_and_clear_bit(regno, regs_in_use))
302		return;
303	fprintf(stderr, "freeing already free'd register %s\n", reg_info_table[regno].name);
304}
305
306struct regclass {
307	const char *name;
308	const unsigned char regs[30];
309};
310
311static struct regclass regclass_8 = { "8-bit", { AL, DL, CL, BL, AH, DH, CH, BH }};
312static struct regclass regclass_16 = { "16-bit", { AX, DX, CX, BX, SI, DI, BP }};
313static struct regclass regclass_32 = { "32-bit", { EAX, EDX, ECX, EBX, ESI, EDI, EBP }};
314static struct regclass regclass_64 = { "64-bit", { EAX_EDX, ECX_EBX, ESI_EDI }};
315
316static struct regclass regclass_32_8 = { "32-bit bytes", { EAX, EDX, ECX, EBX }};
317
318static struct regclass *get_regclass_bits(int bits)
319{
320	switch (bits) {
321	case 8: return &regclass_8;
322	case 16: return &regclass_16;
323	case 64: return &regclass_64;
324	default: return &regclass_32;
325	}
326}
327
328static struct regclass *get_regclass(struct expression *expr)
329{
330	return get_regclass_bits(expr->ctype->bit_size);
331}
332
333static int register_busy(int regno)
334{
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;
338
339		while ((regno = *regs) != NOREG) {
340			regs++;
341			if (test_bit(regno, regs_in_use))
342				goto busy;
343		}
344		return 0;
345	}
346busy:
347	return 1;
348}
349
350static struct storage *get_reg(struct regclass *class)
351{
352	const unsigned char *regs = class->regs;
353	int regno;
354
355	while ((regno = *regs) != NOREG) {
356		regs++;
357		if (register_busy(regno))
358			continue;
359		return get_hardreg(hardreg_storage_table + regno, 1);
360	}
361	fprintf(stderr, "Ran out of %s registers\n", class->name);
362	exit(1);
363}
364
365static struct storage *get_reg_value(struct storage *value, struct regclass *class)
366{
367	struct reg_info *info;
368	struct storage *reg;
369
370	/* Do we already have it somewhere */
371	info = value->reg;
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);
375	}
376
377	reg = get_reg(class);
378	emit_move(value, reg, value->ctype, "reload register");
379	info = reg->reg;
380	info->contains = value;
381	value->reg = info;
382	return reg;
383}
384
385static struct storage *temp_from_bits(unsigned int bit_size)
386{
387	return get_reg(get_regclass_bits(bit_size));
388}
389
390static inline unsigned int pseudo_offset(struct storage *s)
391{
392	if (s->type != STOR_PSEUDO)
393		return 123456;	/* intentionally bogus value */
394
395	return s->offset;
396}
397
398static inline unsigned int arg_offset(struct storage *s)
399{
400	if (s->type != STOR_ARG)
401		return 123456;	/* intentionally bogus value */
402
403	/* FIXME: this is wrong wrong wrong */
404	return current_func->stack_size + ((1 + s->idx) * 4);
405}
406
407static const char *pretty_offset(int ofs)
408{
409	static char esp_buf[64];
410
411	if (ofs)
412		sprintf(esp_buf, "%d(%%esp)", ofs);
413	else
414		strcpy(esp_buf, "(%esp)");
415
416	return esp_buf;
417}
418
419static void stor_sym_init(struct symbol *sym)
420{
421	struct storage *stor;
422	struct symbol_private *priv;
423
424	priv = calloc(1, sizeof(*priv) + sizeof(*stor));
425	if (!priv)
426		die("OOM in stor_sym_init");
427
428	stor = (struct storage *) (priv + 1);
429
430	priv->addr = stor;
431	stor->type = STOR_SYM;
432	stor->sym = sym;
433}
434
435static const char *stor_op_name(struct storage *s)
436{
437	static char name[32];
438
439	switch (s->type) {
440	case STOR_PSEUDO:
441		strcpy(name, pretty_offset((int) pseudo_offset(s)));
442		break;
443	case STOR_ARG:
444		strcpy(name, pretty_offset((int) arg_offset(s)));
445		break;
446	case STOR_SYM:
447		strcpy(name, show_ident(s->sym->ident));
448		break;
449	case STOR_REG:
450		strcpy(name, s->reg->name);
451		break;
452	case STOR_VALUE:
453		sprintf(name, "$%lld", s->value);
454		break;
455	case STOR_LABEL:
456		sprintf(name, "%s.L%d", s->flags & STOR_LABEL_VAL ? "$" : "",
457			s->label);
458		break;
459	case STOR_LABELSYM:
460		sprintf(name, "%s.LS%p", s->flags & STOR_LABEL_VAL ? "$" : "",
461			s->labelsym);
462		break;
463	}
464
465	return name;
466}
467
468static struct atom *new_atom(enum atom_type type)
469{
470	struct atom *atom;
471
472	atom = calloc(1, sizeof(*atom));	/* TODO: chunked alloc */
473	if (!atom)
474		die("nuclear OOM");
475
476	atom->type = type;
477
478	return atom;
479}
480
481static inline void push_cstring(struct function *f, struct string *str,
482				int label)
483{
484	struct atom *atom;
485
486	atom = new_atom(ATOM_CSTR);
487	atom->string = str;
488	atom->label = label;
489
490	add_ptr_list(&f->str_list, atom);	/* note: _not_ atom_list */
491}
492
493static inline void push_atom(struct function *f, struct atom *atom)
494{
495	add_ptr_list(&f->atom_list, atom);
496}
497
498static void push_text_atom(struct function *f, const char *text)
499{
500	struct atom *atom = new_atom(ATOM_TEXT);
501
502	atom->text = strdup(text);
503	atom->text_len = strlen(text);
504
505	push_atom(f, atom);
506}
507
508static struct storage *new_storage(enum storage_type type)
509{
510	struct storage *stor;
511
512	stor = calloc(1, sizeof(*stor));
513	if (!stor)
514		die("OOM in new_storage");
515
516	stor->type = type;
517
518	return stor;
519}
520
521static struct storage *stack_alloc(int n_bytes)
522{
523	struct function *f = current_func;
524	struct storage *stor;
525
526	assert(f != NULL);
527
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;
534	f->pseudo_nr++;
535
536	add_ptr_list(&f->pseudo_list, stor);
537
538	return stor;
539}
540
541static struct storage *new_labelsym(struct symbol *sym)
542{
543	struct storage *stor;
544
545	stor = new_storage(STOR_LABELSYM);
546
547	if (stor) {
548		stor->flags |= STOR_WANTS_FREE;
549		stor->labelsym = sym;
550	}
551
552	return stor;
553}
554
555static struct storage *new_val(long long value)
556{
557	struct storage *stor;
558
559	stor = new_storage(STOR_VALUE);
560
561	if (stor) {
562		stor->flags |= STOR_WANTS_FREE;
563		stor->value = value;
564	}
565
566	return stor;
567}
568
569static int new_label(void)
570{
571	static int label = 0;
572	return ++label;
573}
574
575static void textbuf_push(struct textbuf **buf_p, const char *text)
576{
577	struct textbuf *tmp, *list = *buf_p;
578	unsigned int text_len = strlen(text);
579	unsigned int alloc_len = text_len + 1 + sizeof(*list);
580
581	tmp = calloc(1, alloc_len);
582	if (!tmp)
583		die("OOM on textbuf alloc");
584
585	tmp->text = ((void *) tmp) + sizeof(*tmp);
586	memcpy(tmp->text, text, text_len + 1);
587	tmp->len = text_len;
588
589	/* add to end of list */
590	if (!list) {
591		list = tmp;
592		tmp->prev = tmp;
593	} else {
594		tmp->prev = list->prev;
595		tmp->prev->next = tmp;
596		list->prev = tmp;
597	}
598	tmp->next = list;
599
600	*buf_p = list;
601}
602
603static void textbuf_emit(struct textbuf **buf_p)
604{
605	struct textbuf *tmp, *list = *buf_p;
606
607	while (list) {
608		tmp = list;
609		if (tmp->next == tmp)
610			list = NULL;
611		else {
612			tmp->prev->next = tmp->next;
613			tmp->next->prev = tmp->prev;
614			list = tmp->next;
615		}
616
617		fputs(tmp->text, stdout);
618
619		free(tmp);
620	}
621
622	*buf_p = list;
623}
624
625static void insn(const char *insn, struct storage *op1, struct storage *op2,
626		 const char *comment_in)
627{
628	struct function *f = current_func;
629	struct atom *atom = new_atom(ATOM_INSN);
630
631	assert(insn != NULL);
632
633	strcpy(atom->insn, insn);
634	if (comment_in && (*comment_in))
635		strncpy(atom->comment, comment_in,
636			sizeof(atom->comment) - 1);
637
638	atom->op1 = op1;
639	atom->op2 = op2;
640
641	push_atom(f, atom);
642}
643
644static void emit_comment(const char *fmt, ...)
645{
646	struct function *f = current_func;
647	static char tmpbuf[100] = "\t# ";
648	va_list args;
649	int i;
650
651	va_start(args, fmt);
652	i = vsnprintf(tmpbuf+3, sizeof(tmpbuf)-4, fmt, args);
653	va_end(args);
654	tmpbuf[i+3] = '\n';
655	tmpbuf[i+4] = '\0';
656	push_text_atom(f, tmpbuf);
657}
658
659static void emit_label (int label, const char *comment)
660{
661	struct function *f = current_func;
662	char s[64];
663
664	if (!comment)
665		sprintf(s, ".L%d:\n", label);
666	else
667		sprintf(s, ".L%d:\t\t\t\t\t# %s\n", label, comment);
668
669	push_text_atom(f, s);
670}
671
672static void emit_labelsym (struct symbol *sym, const char *comment)
673{
674	struct function *f = current_func;
675	char s[64];
676
677	if (!comment)
678		sprintf(s, ".LS%p:\n", sym);
679	else
680		sprintf(s, ".LS%p:\t\t\t\t# %s\n", sym, comment);
681
682	push_text_atom(f, s);
683}
684
685void emit_unit_begin(const char *basename)
686{
687	printf("\t.file\t\"%s\"\n", basename);
688}
689
690void emit_unit_end(void)
691{
692	textbuf_emit(&unit_post_text);
693	printf("\t.ident\t\"sparse silly x86 backend (version %s)\"\n", sparse_version);
694}
695
696/* conditionally switch sections */
697static void emit_section(const char *s)
698{
699	if (s == current_section)
700		return;
701	if (current_section && (!strcmp(s, current_section)))
702		return;
703
704	printf("\t%s\n", s);
705	current_section = s;
706}
707
708static void emit_insn_atom(struct function *f, struct atom *atom)
709{
710	char s[128];
711	char comment[64];
712	struct storage *op1 = atom->op1;
713	struct storage *op2 = atom->op2;
714
715	if (atom->comment[0])
716		sprintf(comment, "\t\t# %s", atom->comment);
717	else
718		comment[0] = 0;
719
720	if (atom->op2) {
721		char tmp[16];
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);
729	else
730		sprintf(s, "\t%s\t%s%s\n",
731			atom->insn,
732			comment[0] ? "\t\t" : "", comment);
733
734	if (write(STDOUT_FILENO, s, strlen(s)) < 0)
735		die("can't write to stdout");
736}
737
738static void emit_atom_list(struct function *f)
739{
740	struct atom *atom;
741
742	FOR_EACH_PTR(f->atom_list, atom) {
743		switch (atom->type) {
744		case ATOM_TEXT: {
745			if (write(STDOUT_FILENO, atom->text, atom->text_len) < 0)
746				die("can't write to stdout");
747			break;
748		}
749		case ATOM_INSN:
750			emit_insn_atom(f, atom);
751			break;
752		case ATOM_CSTR:
753			assert(0);
754			break;
755		}
756	} END_FOR_EACH_PTR(atom);
757}
758
759static void emit_string_list(struct function *f)
760{
761	struct atom *atom;
762
763	emit_section(".section\t.rodata");
764
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));
769
770		free(atom);
771	} END_FOR_EACH_PTR(atom);
772}
773
774static void func_cleanup(struct function *f)
775{
776	struct storage *stor;
777	struct atom *atom;
778
779	FOR_EACH_PTR(f->atom_list, atom) {
780		if ((atom->type == ATOM_TEXT) && (atom->text))
781			free(atom->text);
782		if (atom->op1 && (atom->op1->flags & STOR_WANTS_FREE))
783			free(atom->op1);
784		if (atom->op2 && (atom->op2->flags & STOR_WANTS_FREE))
785			free(atom->op2);
786		free(atom);
787	} END_FOR_EACH_PTR(atom);
788
789	FOR_EACH_PTR(f->pseudo_list, stor) {
790		free(stor);
791	} END_FOR_EACH_PTR(stor);
792
793	free_ptr_list(&f->pseudo_list);
794	free(f);
795}
796
797/* function prologue */
798static void emit_func_pre(struct symbol *sym)
799{
800	struct function *f;
801	struct symbol *arg;
802	unsigned int i, argc = 0, alloc_len;
803	unsigned char *mem;
804	struct symbol_private *privbase;
805	struct storage *storage_base;
806	struct symbol *base_type = sym->ctype.base_type;
807
808	FOR_EACH_PTR(base_type->arguments, arg) {
809		argc++;
810	} END_FOR_EACH_PTR(arg);
811
812	alloc_len =
813		sizeof(*f) +
814		(argc * sizeof(struct symbol *)) +
815		(argc * sizeof(struct symbol_private)) +
816		(argc * sizeof(struct storage));
817	mem = calloc(1, alloc_len);
818	if (!mem)
819		die("OOM on func info");
820
821	f		=  (struct function *) mem;
822	mem		+= sizeof(*f);
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;
828
829	f->argc = argc;
830	f->ret_target = new_label();
831
832	i = 0;
833	FOR_EACH_PTR(base_type->arguments, arg) {
834		f->argv[i] = 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];
839		i++;
840	} END_FOR_EACH_PTR(arg);
841
842	assert(current_func == NULL);
843	current_func = f;
844}
845
846/* function epilogue */
847static void emit_func_post(struct symbol *sym)
848{
849	const char *name = show_ident(sym->ident);
850	struct function *f = current_func;
851	int stack_size = f->stack_size;
852
853	if (f->str_list)
854		emit_string_list(f);
855
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);
862
863	if (stack_size) {
864		char pseudo_const[16];
865
866		sprintf(pseudo_const, "$%d", stack_size);
867		printf("\tsubl\t%s, %%esp\n", pseudo_const);
868	}
869
870	/* function epilogue */
871
872	/* jump target for 'return' statements */
873	emit_label(f->ret_target, NULL);
874
875	if (stack_size) {
876		struct storage *val;
877
878		val = new_storage(STOR_VALUE);
879		val->value = (long long) (stack_size);
880		val->flags = STOR_WANTS_FREE;
881
882		insn("addl", val, REG_ESP, NULL);
883	}
884
885	insn("ret", NULL, NULL, NULL);
886
887	/* output everything to stdout */
888	fflush(stdout);		/* paranoia; needed? */
889	emit_atom_list(f);
890
891	/* function footer */
892	name = show_ident(sym->ident);
893	printf("\t.size\t%s, .-%s\n", name, name);
894
895	func_cleanup(f);
896	current_func = NULL;
897}
898
899/* emit object (a.k.a. variable, a.k.a. data) prologue */
900static void emit_object_pre(const char *name, unsigned long modifiers,
901			    unsigned long alignment, unsigned int byte_size)
902{
903	if ((modifiers & MOD_STATIC) == 0)
904		printf(".globl %s\n", name);
905	emit_section(".data");
906	if (alignment)
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);
911}
912
913/* emit value (only) for an initializer scalar */
914static void emit_scalar(struct expression *expr, unsigned int bit_size)
915{
916	const char *type;
917	long long ll;
918
919	assert(expr->type == EXPR_VALUE);
920
921	if (expr->value == 0ULL) {
922		printf("\t.zero\t%d\n", bit_size / 8);
923		return;
924	}
925
926	ll = (long long) expr->value;
927
928	switch (bit_size) {
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;
934	}
935
936	assert(type != NULL);
937
938	printf("\t.%s\t%lld\n", type, ll);
939}
940
941static void emit_global_noinit(const char *name, unsigned long modifiers,
942			       unsigned long alignment, unsigned int byte_size)
943{
944	char s[64];
945
946	if (modifiers & MOD_STATIC) {
947		sprintf(s, "\t.local\t%s\n", name);
948		textbuf_push(&unit_post_text, s);
949	}
950	if (alignment)
951		sprintf(s, "\t.comm\t%s,%d,%lu\n", name, byte_size, alignment);
952	else
953		sprintf(s, "\t.comm\t%s,%d\n", name, byte_size);
954	textbuf_push(&unit_post_text, s);
955}
956
957static int ea_current, ea_last;
958
959static void emit_initializer(struct symbol *sym,
960			     struct expression *expr)
961{
962	int distance = ea_current - ea_last - 1;
963
964	if (distance > 0)
965		printf("\t.zero\t%d\n", (sym->bit_size / 8) * distance);
966
967	if (expr->type == EXPR_VALUE) {
968		struct symbol *base_type = sym->ctype.base_type;
969		assert(base_type != NULL);
970
971		emit_scalar(expr, sym->bit_size / get_expression_value(base_type->array_size));
972		return;
973	}
974	if (expr->type != EXPR_INITIALIZER)
975		return;
976
977	assert(0); /* FIXME */
978}
979
980static int sort_array_cmp(const struct expression *a,
981			  const struct expression *b)
982{
983	int a_ofs = 0, b_ofs = 0;
984
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;
989
990	return a_ofs - b_ofs;
991}
992
993/* move to front-end? */
994static void sort_array(struct expression *expr)
995{
996	struct expression *entry, **list;
997	unsigned int elem, sorted, i;
998
999	elem = expression_list_size(expr->expr_list);
1000	if (!elem)
1001		return;
1002
1003	list = malloc(sizeof(entry) * elem);
1004	if (!list)
1005		die("OOM in sort_array");
1006
1007	/* this code is no doubt evil and ignores EXPR_INDEX possibly
1008	 * to its detriment and other nasty things.  improvements
1009	 * welcome.
1010	 */
1011	i = 0;
1012	sorted = 0;
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 */
1016			if (sorted == 0) {
1017				list[0] = entry;
1018				sorted = 1;
1019			} else {
1020				for (i = 0; i < sorted; i++)
1021					if (sort_array_cmp(entry, list[i]) <= 0)
1022						break;
1023
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...
1030				 */
1031				if (i != sorted)
1032					memmove(&list[i + 1], &list[i],
1033						(sorted - i) * sizeof(entry));
1034				list[i] = entry;
1035				sorted++;
1036			}
1037		}
1038	} END_FOR_EACH_PTR(entry);
1039
1040	i = 0;
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);
1045
1046	free(list);
1047}
1048
1049static void emit_array(struct symbol *sym)
1050{
1051	struct symbol *base_type = sym->ctype.base_type;
1052	struct expression *expr = sym->initializer;
1053	struct expression *entry;
1054
1055	assert(base_type != NULL);
1056
1057	stor_sym_init(sym);
1058
1059	ea_last = -1;
1060
1061	emit_object_pre(show_ident(sym->ident), sym->ctype.modifiers,
1062		        sym->ctype.alignment,
1063			sym->bit_size / 8);
1064
1065	sort_array(expr);
1066
1067	FOR_EACH_PTR(expr->expr_list, entry) {
1068		if (entry->type == EXPR_VALUE) {
1069			ea_current = 0;
1070			emit_initializer(sym, entry);
1071			ea_last = ea_current;
1072		} else if (entry->type == EXPR_POS) {
1073			ea_current =
1074			    entry->init_offset / (base_type->bit_size / 8);
1075			emit_initializer(sym, entry->init_expr);
1076			ea_last = ea_current;
1077		}
1078	} END_FOR_EACH_PTR(entry);
1079}
1080
1081void emit_one_symbol(struct symbol *sym)
1082{
1083	x86_symbol(sym);
1084}
1085
1086static void emit_copy(struct storage *dest, struct storage *src,
1087		      struct symbol *ctype)
1088{
1089	struct storage *reg = NULL;
1090	unsigned int bit_size;
1091
1092	/* FIXME: Bitfield copy! */
1093
1094	bit_size = src->size * 8;
1095	if (!bit_size)
1096		bit_size = 32;
1097	if ((src->type == STOR_ARG) && (bit_size < 32))
1098		bit_size = 32;
1099
1100	reg = temp_from_bits(bit_size);
1101	emit_move(src, reg, ctype, "begin copy ..");
1102
1103	bit_size = dest->size * 8;
1104	if (!bit_size)
1105		bit_size = 32;
1106	if ((dest->type == STOR_ARG) && (bit_size < 32))
1107		bit_size = 32;
1108
1109	emit_move(reg, dest, ctype, ".... end copy");
1110	put_reg(reg);
1111}
1112
1113static void emit_store(struct expression *dest_expr, struct storage *dest,
1114		       struct storage *src, int bits)
1115{
1116	/* FIXME: Bitfield store! */
1117	printf("\tst.%d\t\tv%d,[v%d]\n", bits, src->pseudo, dest->pseudo);
1118}
1119
1120static void emit_scalar_noinit(struct symbol *sym)
1121{
1122	emit_global_noinit(show_ident(sym->ident),
1123			   sym->ctype.modifiers, sym->ctype.alignment,
1124			   sym->bit_size / 8);
1125	stor_sym_init(sym);
1126}
1127
1128static void emit_array_noinit(struct symbol *sym)
1129{
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));
1133	stor_sym_init(sym);
1134}
1135
1136static const char *opbits(const char *insn, unsigned int bits)
1137{
1138	static char opbits_str[32];
1139	char c;
1140
1141	switch (bits) {
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;
1147	}
1148
1149	sprintf(opbits_str, "%s%c", insn, c);
1150
1151	return opbits_str;
1152}
1153
1154static void emit_move(struct storage *src, struct storage *dest,
1155		      struct symbol *ctype, const char *comment)
1156{
1157	unsigned int bits;
1158	unsigned int is_signed;
1159	unsigned int is_dest = (src->type == STOR_REG);
1160	const char *opname;
1161
1162	if (ctype) {
1163		bits = ctype->bit_size;
1164		is_signed = is_signed_type(ctype);
1165	} else {
1166		bits = 32;
1167		is_signed = 0;
1168	}
1169
1170	/*
1171	 * Are we moving from a register to a register?
1172	 * Make the new reg to be the "cache".
1173	 */
1174	if ((dest->type == STOR_REG) && (src->type == STOR_REG)) {
1175		struct storage *backing;
1176
1177reg_reg_move:
1178		if (dest == src)
1179			return;
1180
1181		backing = src->reg->contains;
1182		if (backing) {
1183			/* Is it still valid? */
1184			if (backing->reg != src->reg)
1185				backing = NULL;
1186			else
1187				backing->reg = dest->reg;
1188		}
1189		dest->reg->contains = backing;
1190		insn("mov", src, dest, NULL);
1191		return;
1192	}
1193
1194	/*
1195	 * Are we moving to a register from a non-reg?
1196	 *
1197	 * See if we have the non-reg source already cached
1198	 * in a register..
1199	 */
1200	if (dest->type == STOR_REG) {
1201		if (src->reg) {
1202			struct reg_info *info = src->reg;
1203			if (info->contains == src) {
1204				src = reginfo_reg(info);
1205				goto reg_reg_move;
1206			}
1207		}
1208		dest->reg->contains = src;
1209		src->reg = dest->reg;
1210	}
1211
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;
1216	}
1217
1218	if ((bits == 8) || (bits == 16)) {
1219		if (is_dest)
1220			opname = "mov";
1221		else
1222			opname = is_signed ? "movsx" : "movzx";
1223	} else
1224		opname = "mov";
1225
1226	insn(opbits(opname, bits), src, dest, comment);
1227}
1228
1229static struct storage *emit_compare(struct expression *expr)
1230{
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;
1237
1238	switch(expr->op) {
1239	case '<': 		opname = "setl";	break;
1240	case '>':		opname = "setg";	break;
1241	case SPECIAL_LTE:
1242				opname = "setle";	break;
1243	case SPECIAL_GTE:
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;
1255	default:
1256		assert(0);
1257		break;
1258	}
1259
1260	/* init EDX to 0 */
1261	val = new_storage(STOR_VALUE);
1262	val->flags = STOR_WANTS_FREE;
1263
1264	reg1 = get_reg(&regclass_32_8);
1265	emit_move(val, reg1, NULL, NULL);
1266
1267	/* move op1 into EAX */
1268	reg2 = get_reg_value(left, get_regclass(expr->left));
1269
1270	/* perform comparison, RHS (op1, right) and LHS (op2, EAX) */
1271	insn(opbits("cmp", right_bits), right, reg2, NULL);
1272	put_reg(reg2);
1273
1274	/* store result of operation, 0 or 1, in DL using SETcc */
1275	insn(opname, byte_reg(reg1), NULL, NULL);
1276
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");
1280	put_reg(reg1);
1281
1282	return new;
1283}
1284
1285static struct storage *emit_value(struct expression *expr)
1286{
1287#if 0 /* old and slow way */
1288	struct storage *new = stack_alloc(4);
1289	struct storage *val;
1290
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);
1295
1296	return new;
1297#else
1298	struct storage *val;
1299
1300	val = new_storage(STOR_VALUE);
1301	val->value = (long long) expr->value;
1302
1303	return val;	/* FIXME: memory leak */
1304#endif
1305}
1306
1307static struct storage *emit_divide(struct expression *expr, struct storage *left, struct storage *right)
1308{
1309	struct storage *eax_edx;
1310	struct storage *reg, *new;
1311	struct storage *val = new_storage(STOR_VALUE);
1312
1313	emit_comment("begin DIVIDE");
1314	eax_edx = get_hardreg(hardreg_storage_table + EAX_EDX, 1);
1315
1316	/* init EDX to 0 */
1317	val->flags = STOR_WANTS_FREE;
1318	emit_move(val, REG_EDX, NULL, NULL);
1319
1320	new = stack_alloc(expr->ctype->bit_size / 8);
1321
1322	/* EAX is dividend */
1323	emit_move(left, REG_EAX, NULL, NULL);
1324
1325	reg = get_reg_value(right, &regclass_32);
1326
1327	/* perform binop */
1328	insn("div", reg, REG_EAX, NULL);
1329	put_reg(reg);
1330
1331	reg = REG_EAX;
1332	if (expr->op == '%')
1333		reg = REG_EDX;
1334	emit_move(reg, new, NULL, NULL);
1335
1336	put_reg(eax_edx);
1337	emit_comment("end DIVIDE");
1338	return new;
1339}
1340
1341static struct storage *emit_binop(struct expression *expr)
1342{
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;
1349	char opstr[16];
1350	int is_signed;
1351
1352	/* Divides have special register constraints */
1353	if ((expr->op == '/') || (expr->op == '%'))
1354		return emit_divide(expr, left, right);
1355
1356	is_signed = is_signed_type(expr->ctype);
1357
1358	switch (expr->op) {
1359	case '+':
1360		opname = "add";
1361		break;
1362	case '-':
1363		opname = "sub";
1364		break;
1365	case '&':
1366		opname = "and";
1367		break;
1368	case '|':
1369		opname = "or";
1370		break;
1371	case '^':
1372		opname = "xor";
1373		break;
1374	case SPECIAL_LEFTSHIFT:
1375		opname = "shl";
1376		break;
1377	case SPECIAL_RIGHTSHIFT:
1378		if (is_signed)
1379			opname = "sar";
1380		else
1381			opname = "shr";
1382		break;
1383	case '*':
1384		if (is_signed)
1385			opname = "imul";
1386		else
1387			opname = "mul";
1388		break;
1389	case SPECIAL_LOGICAL_AND:
1390		warning(expr->pos, "bogus bitwise and for logical op (should use '2*setne + and' or something)");
1391		opname = "and";
1392		break;
1393	case SPECIAL_LOGICAL_OR:
1394		warning(expr->pos, "bogus bitwise or for logical op (should use 'or + setne' or something)");
1395		opname = "or";
1396		break;
1397	default:
1398		error_die(expr->pos, "unhandled binop '%s'\n", show_special(expr->op));
1399		break;
1400	}
1401
1402	dest = get_reg_value(right, &regclass_32);
1403	src = get_reg_value(left, &regclass_32);
1404	switch (expr->ctype->bit_size) {
1405	case 8:
1406		suffix = "b";
1407		break;
1408	case 16:
1409		suffix = "w";
1410		break;
1411	case 32:
1412		suffix = "l";
1413		break;
1414	case 64:
1415		suffix = "q";		/* FIXME */
1416		break;
1417	default:
1418		assert(0);
1419		break;
1420	}
1421
1422	snprintf(opstr, sizeof(opstr), "%s%s", opname, suffix);
1423
1424	/* perform binop */
1425	insn(opstr, src, dest, NULL);
1426	put_reg(src);
1427
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");
1431
1432	put_reg(dest);
1433
1434	return new;
1435}
1436
1437static int emit_conditional_test(struct storage *val)
1438{
1439	struct storage *reg;
1440	struct storage *target_val;
1441	int target_false;
1442
1443	/* load result into EAX */
1444	emit_comment("begin if/conditional");
1445	reg = get_reg_value(val, &regclass_32);
1446
1447	/* compare result with zero */
1448	insn("test", reg, reg, NULL);
1449	put_reg(reg);
1450
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);
1457
1458	return target_false;
1459}
1460
1461static int emit_conditional_end(int target_false)
1462{
1463	struct storage *cond_end_st;
1464	int cond_end;
1465
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.
1469	 */
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);
1475
1476	/* if we have both if-true and if-false statements,
1477	 * the failed-conditional case will fall through to here
1478	 */
1479	emit_label(target_false, NULL);
1480
1481	return cond_end;
1482}
1483
1484static void emit_if_conditional(struct statement *stmt)
1485{
1486	struct storage *val;
1487	int cond_end;
1488
1489	/* emit test portion of conditional */
1490	val = x86_expression(stmt->if_conditional);
1491	cond_end = emit_conditional_test(val);
1492
1493	/* emit if-true statement */
1494	x86_statement(stmt->if_true);
1495
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);
1500	}
1501
1502	/* end of conditional; jump target for if-true branch */
1503	emit_label(cond_end, "end if");
1504}
1505
1506static struct storage *emit_inc_dec(struct expression *expr, int postop)
1507{
1508	struct storage *addr = x86_address_gen(expr->unop);
1509	struct storage *retval;
1510	char opname[16];
1511
1512	strcpy(opname, opbits(expr->op == SPECIAL_INCREMENT ? "inc" : "dec",
1513			      expr->ctype->bit_size));
1514
1515	if (postop) {
1516		struct storage *new = stack_alloc(4);
1517
1518		emit_copy(new, addr, expr->unop->ctype);
1519
1520		retval = new;
1521	} else
1522		retval = addr;
1523
1524	insn(opname, addr, NULL, NULL);
1525
1526	return retval;
1527}
1528
1529static struct storage *emit_postop(struct expression *expr)
1530{
1531	return emit_inc_dec(expr, 1);
1532}
1533
1534static struct storage *emit_return_stmt(struct statement *stmt)
1535{
1536	struct function *f = current_func;
1537	struct expression *expr = stmt->ret_value;
1538	struct storage *val = NULL, *jmplbl;
1539
1540	if (expr && expr->ctype) {
1541		val = x86_expression(expr);
1542		assert(val != NULL);
1543		emit_move(val, REG_EAX, expr->ctype, "return");
1544	}
1545
1546	jmplbl = new_storage(STOR_LABEL);
1547	jmplbl->flags |= STOR_WANTS_FREE;
1548	jmplbl->label = f->ret_target;
1549	insn("jmp", jmplbl, NULL, NULL);
1550
1551	return val;
1552}
1553
1554static struct storage *emit_conditional_expr(struct expression *expr)
1555{
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;
1559
1560	/* evaluate conditional */
1561	cond = x86_expression(expr->conditional);
1562	target_false = emit_conditional_test(cond);
1563
1564	/* handle if-true part of the expression */
1565	stot = x86_expression(expr->cond_true);
1566
1567	emit_copy(new, stot, expr->ctype);
1568
1569	cond_end = emit_conditional_end(target_false);
1570
1571	/* handle if-false part of the expression */
1572	stof = x86_expression(expr->cond_false);
1573
1574	emit_copy(new, stof, expr->ctype);
1575
1576	/* end of conditional; jump target for if-true branch */
1577	emit_label(cond_end, "end conditional");
1578
1579	return new;
1580}
1581
1582static struct storage *emit_select_expr(struct expression *expr)
1583{
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);
1589
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));
1594
1595	/*
1596	 * Do the actual select: check the conditional for zero,
1597	 * move false over true if zero
1598	 */
1599	insn("test", reg_cond, reg_cond, NULL);
1600	insn("cmovz", reg_false, reg_true, NULL);
1601
1602	/* Store it back */
1603	emit_move(reg_true, new, expr->ctype, NULL);
1604	put_reg(reg_cond);
1605	put_reg(reg_true);
1606	put_reg(reg_false);
1607	emit_comment("end SELECT");
1608	return new;
1609}
1610
1611static struct storage *emit_symbol_expr_init(struct symbol *sym)
1612{
1613	struct expression *expr = sym->initializer;
1614	struct symbol_private *priv = sym->aux;
1615
1616	if (priv == NULL) {
1617		priv = calloc(1, sizeof(*priv));
1618		sym->aux = priv;
1619
1620		if (expr == NULL) {
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);
1625			priv->addr = new;
1626		} else {
1627			priv->addr = x86_expression(expr);
1628		}
1629	}
1630
1631	return priv->addr;
1632}
1633
1634static struct storage *emit_string_expr(struct expression *expr)
1635{
1636	struct function *f = current_func;
1637	int label = new_label();
1638	struct storage *new;
1639
1640	push_cstring(f, expr->string, label);
1641
1642	new = new_storage(STOR_LABEL);
1643	new->label = label;
1644	new->flags = STOR_LABEL_VAL | STOR_WANTS_FREE;
1645	return new;
1646}
1647
1648static struct storage *emit_cast_expr(struct expression *expr)
1649{
1650	struct symbol *old_type, *new_type;
1651	struct storage *op = x86_expression(expr->cast_expression);
1652	int oldbits, newbits;
1653	struct storage *new;
1654
1655	old_type = expr->cast_expression->ctype;
1656	new_type = expr->cast_type;
1657
1658	oldbits = old_type->bit_size;
1659	newbits = new_type->bit_size;
1660	if (oldbits >= newbits)
1661		return op;
1662
1663	emit_move(op, REG_EAX, old_type, "begin cast ..");
1664
1665	new = stack_alloc(newbits / 8);
1666	emit_move(REG_EAX, new, new_type, ".... end cast");
1667
1668	return new;
1669}
1670
1671static struct storage *emit_regular_preop(struct expression *expr)
1672{
1673	struct storage *target = x86_expression(expr->unop);
1674	struct storage *val, *new = stack_alloc(4);
1675	const char *opname = NULL;
1676
1677	switch (expr->op) {
1678	case '!':
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);
1686
1687		break;
1688	case '~':
1689		opname = "not";
1690	case '-':
1691		if (!opname)
1692			opname = "neg";
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);
1696		break;
1697	default:
1698		assert(0);
1699		break;
1700	}
1701
1702	return new;
1703}
1704
1705static void emit_case_statement(struct statement *stmt)
1706{
1707	emit_labelsym(stmt->case_label, NULL);
1708	x86_statement(stmt->case_statement);
1709}
1710
1711static void emit_switch_statement(struct statement *stmt)
1712{
1713	struct storage *val = x86_expression(stmt->switch_expression);
1714	struct symbol *sym, *default_sym = NULL;
1715	struct storage *labelsym, *label;
1716	int switch_end = 0;
1717
1718	emit_move(val, REG_EAX, stmt->switch_expression->ctype, "begin case");
1719
1720	/*
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
1724	 */
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;
1729
1730		/* default: */
1731		if (!expr)
1732			default_sym = sym;
1733
1734		/* case NNN: */
1735		else {
1736			struct storage *case_val = new_val(expr->value);
1737
1738			assert (expr->type == EXPR_VALUE);
1739
1740			insn("cmpl", case_val, REG_EAX, NULL);
1741
1742			if (!to) {
1743				labelsym = new_labelsym(sym);
1744				insn("je", labelsym, NULL, NULL);
1745			} else {
1746				int next_test;
1747
1748				label = new_storage(STOR_LABEL);
1749				label->flags |= STOR_WANTS_FREE;
1750				label->label = next_test = new_label();
1751
1752				/* FIXME: signed/unsigned */
1753				insn("jl", label, NULL, NULL);
1754
1755				case_val = new_val(to->value);
1756				insn("cmpl", case_val, REG_EAX, NULL);
1757
1758				/* TODO: implement and use refcounting... */
1759				label = new_storage(STOR_LABEL);
1760				label->flags |= STOR_WANTS_FREE;
1761				label->label = next_test;
1762
1763				/* FIXME: signed/unsigned */
1764				insn("jg", label, NULL, NULL);
1765
1766				labelsym = new_labelsym(sym);
1767				insn("jmp", labelsym, NULL, NULL);
1768
1769				emit_label(next_test, NULL);
1770			}
1771		}
1772	} END_FOR_EACH_PTR(sym);
1773
1774	if (default_sym) {
1775		labelsym = new_labelsym(default_sym);
1776		insn("jmp", labelsym, NULL, "default");
1777	} else {
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");
1782	}
1783
1784	x86_statement(stmt->switch_statement);
1785
1786	if (stmt->switch_break->used)
1787		emit_labelsym(stmt->switch_break, NULL);
1788
1789	if (switch_end)
1790		emit_label(switch_end, NULL);
1791}
1792
1793static void x86_struct_member(struct symbol *sym)
1794{
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);
1796	printf("\n");
1797}
1798
1799static void x86_symbol(struct symbol *sym)
1800{
1801	struct symbol *type;
1802
1803	if (!sym)
1804		return;
1805
1806	type = sym->ctype.base_type;
1807	if (!type)
1808		return;
1809
1810	/*
1811	 * Show actual implementation information
1812	 */
1813	switch (type->type) {
1814
1815	case SYM_ARRAY:
1816		if (sym->initializer)
1817			emit_array(sym);
1818		else
1819			emit_array_noinit(sym);
1820		break;
1821
1822	case SYM_BASETYPE:
1823		if (sym->initializer) {
1824			emit_object_pre(show_ident(sym->ident),
1825					sym->ctype.modifiers,
1826				        sym->ctype.alignment,
1827					sym->bit_size / 8);
1828			emit_scalar(sym->initializer, sym->bit_size);
1829			stor_sym_init(sym);
1830		} else
1831			emit_scalar_noinit(sym);
1832		break;
1833
1834	case SYM_STRUCT:
1835	case SYM_UNION: {
1836		struct symbol *member;
1837
1838		printf(" {\n");
1839		FOR_EACH_PTR(type->symbol_list, member) {
1840			x86_struct_member(member);
1841		} END_FOR_EACH_PTR(member);
1842		printf("}\n");
1843		break;
1844	}
1845
1846	case SYM_FN: {
1847		struct statement *stmt = type->stmt;
1848		if (stmt) {
1849			emit_func_pre(sym);
1850			x86_statement(stmt);
1851			emit_func_post(sym);
1852		}
1853		break;
1854	}
1855
1856	default:
1857		break;
1858	}
1859
1860	if (sym->initializer && (type->type != SYM_BASETYPE) &&
1861	    (type->type != SYM_ARRAY)) {
1862		printf(" = \n");
1863		x86_expression(sym->initializer);
1864	}
1865}
1866
1867static void x86_symbol_init(struct symbol *sym);
1868
1869static void x86_symbol_decl(struct symbol_list *syms)
1870{
1871	struct symbol *sym;
1872	FOR_EACH_PTR(syms, sym) {
1873		x86_symbol_init(sym);
1874	} END_FOR_EACH_PTR(sym);
1875}
1876
1877static void loopstk_push(int cont_lbl, int loop_bottom_lbl)
1878{
1879	struct function *f = current_func;
1880	struct loop_stack *ls;
1881
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;
1886	f->loop_stack = ls;
1887}
1888
1889static void loopstk_pop(void)
1890{
1891	struct function *f = current_func;
1892	struct loop_stack *ls;
1893
1894	assert(f->loop_stack != NULL);
1895	ls = f->loop_stack;
1896	f->loop_stack = f->loop_stack->next;
1897	free(ls);
1898}
1899
1900static int loopstk_break(void)
1901{
1902	return current_func->loop_stack->loop_bottom_lbl;
1903}
1904
1905static int loopstk_continue(void)
1906{
1907	return current_func->loop_stack->continue_lbl;
1908}
1909
1910static void emit_loop(struct statement *stmt)
1911{
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;
1920
1921	loop_bottom = new_label();
1922	loop_continue = new_label();
1923	loopstk_push(loop_continue, loop_bottom);
1924
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");
1930	}
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");
1939				have_bottom = 1;
1940			}
1941		} else {
1942			struct storage *lbv = new_storage(STOR_LABEL);
1943			lbv->label = loop_bottom;
1944			lbv->flags = STOR_WANTS_FREE;
1945			have_bottom = 1;
1946
1947			val = x86_expression(pre_condition);
1948
1949			emit_move(val, REG_EAX, NULL, "loop pre condition");
1950			insn("test", REG_EAX, REG_EAX, NULL);
1951			insn("jz", lbv, NULL, NULL);
1952		}
1953	}
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");
1969		}
1970	} else {
1971		struct storage *lbv = new_storage(STOR_LABEL);
1972		lbv->label = loop_top;
1973		lbv->flags = STOR_WANTS_FREE;
1974
1975		val = x86_expression(post_condition);
1976
1977		emit_move(val, REG_EAX, NULL, "loop post condition");
1978		insn("test", REG_EAX, REG_EAX, NULL);
1979		insn("jnz", lbv, NULL, NULL);
1980	}
1981	if (have_bottom || stmt->iterator_break->used)
1982		emit_label(loop_bottom, "loop bottom");
1983
1984	loopstk_pop();
1985}
1986
1987/*
1988 * Print out a statement
1989 */
1990static struct storage *x86_statement(struct statement *stmt)
1991{
1992	if (!stmt)
1993		return NULL;
1994	switch (stmt->type) {
1995	default:
1996		return NULL;
1997	case STMT_RETURN:
1998		return emit_return_stmt(stmt);
1999	case STMT_DECLARATION:
2000		x86_symbol_decl(stmt->declaration);
2001		break;
2002	case STMT_COMPOUND: {
2003		struct statement *s;
2004		struct storage *last = NULL;
2005
2006		FOR_EACH_PTR(stmt->stmts, s) {
2007			last = x86_statement(s);
2008		} END_FOR_EACH_PTR(s);
2009
2010		return last;
2011	}
2012
2013	case STMT_EXPRESSION:
2014		return x86_expression(stmt->expression);
2015	case STMT_IF:
2016		emit_if_conditional(stmt);
2017		return NULL;
2018
2019	case STMT_CASE:
2020		emit_case_statement(stmt);
2021		break;
2022	case STMT_SWITCH:
2023		emit_switch_statement(stmt);
2024		break;
2025
2026	case STMT_ITERATOR:
2027		emit_loop(stmt);
2028		break;
2029
2030	case STMT_NONE:
2031		break;
2032
2033	case STMT_LABEL:
2034		printf(".L%p:\n", stmt->label_identifier);
2035		x86_statement(stmt->label_statement);
2036		break;
2037
2038	case STMT_GOTO:
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");
2052		} else {
2053			struct storage *labelsym = new_labelsym(stmt->goto_label);
2054			insn("jmp", labelsym, NULL, NULL);
2055		}
2056		break;
2057	case STMT_ASM:
2058		printf("\tasm( .... )\n");
2059		break;
2060	}
2061	return NULL;
2062}
2063
2064static struct storage *x86_call_expression(struct expression *expr)
2065{
2066	struct function *f = current_func;
2067	struct symbol *direct;
2068	struct expression *arg, *fn;
2069	struct storage *retval, *fncall;
2070	int framesize;
2071	char s[64];
2072
2073	if (!expr->ctype) {
2074		warning(expr->pos, "\tcall with no type!");
2075		return NULL;
2076	}
2077
2078	framesize = 0;
2079	FOR_EACH_PTR_REVERSE(expr->args, arg) {
2080		struct storage *new = x86_expression(arg);
2081		int size = arg->ctype->bit_size;
2082
2083		/*
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
2088		 * than 32 bits.
2089		 */
2090		if (size < 32)
2091			size = 32;
2092		insn("pushl", new, NULL,
2093		     !framesize ? "begin function call" : NULL);
2094
2095		framesize += bits_to_bytes(size);
2096	} END_FOR_EACH_PTR_REVERSE(arg);
2097
2098	fn = expr->fn;
2099
2100	/* Remove dereference, if any */
2101	direct = NULL;
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)
2106				direct = sym;
2107		}
2108	}
2109	if (direct) {
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);
2114	} else {
2115		fncall = x86_expression(fn);
2116		emit_move(fncall, REG_EAX, fn->ctype, NULL);
2117
2118		strcpy(s, "\tcall\t*%eax\n");
2119		push_text_atom(f, s);
2120	}
2121
2122	/* FIXME: pay attention to BITS_IN_POINTER */
2123	if (framesize) {
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);
2128	}
2129
2130	retval = stack_alloc(4);
2131	emit_move(REG_EAX, retval, NULL, "end function call");
2132
2133	return retval;
2134}
2135
2136static struct storage *x86_address_gen(struct expression *expr)
2137{
2138	struct function *f = current_func;
2139	struct storage *addr;
2140	struct storage *new;
2141	char s[32];
2142
2143	addr = x86_expression(expr->unop);
2144	if (expr->unop->type == EXPR_SYMBOL)
2145		return addr;
2146
2147	emit_move(addr, REG_EAX, NULL, "begin deref ..");
2148
2149	/* FIXME: operand size */
2150	strcpy(s, "\tmovl\t(%eax), %ecx\n");
2151	push_text_atom(f, s);
2152
2153	new = stack_alloc(4);
2154	emit_move(REG_ECX, new, NULL, ".... end deref");
2155
2156	return new;
2157}
2158
2159static struct storage *x86_assignment(struct expression *expr)
2160{
2161	struct expression *target = expr->left;
2162	struct storage *val, *addr;
2163
2164	if (!expr->ctype)
2165		return NULL;
2166
2167	val = x86_expression(expr->right);
2168	addr = x86_address_gen(target);
2169
2170	switch (val->type) {
2171	/* copy, where both operands are memory */
2172	case STOR_PSEUDO:
2173	case STOR_ARG:
2174		emit_copy(addr, val, expr->ctype);
2175		break;
2176
2177	/* copy, one or zero operands are memory */
2178	case STOR_REG:
2179	case STOR_SYM:
2180	case STOR_VALUE:
2181	case STOR_LABEL:
2182		emit_move(val, addr, expr->left->ctype, NULL);
2183		break;
2184
2185	case STOR_LABELSYM:
2186		assert(0);
2187		break;
2188	}
2189	return val;
2190}
2191
2192static int x86_initialization(struct symbol *sym, struct expression *expr)
2193{
2194	struct storage *val, *addr;
2195	int bits;
2196
2197	if (!expr->ctype)
2198		return 0;
2199
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);
2206	return 0;
2207}
2208
2209static struct storage *x86_access(struct expression *expr)
2210{
2211	return x86_address_gen(expr);
2212}
2213
2214static struct storage *x86_preop(struct expression *expr)
2215{
2216	/*
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..
2220	 */
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);
2226}
2227
2228static struct storage *x86_symbol_expr(struct symbol *sym)
2229{
2230	struct storage *new = stack_alloc(4);
2231
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));
2234		return new;
2235	}
2236	if (sym->ctype.modifiers & MOD_ADDRESSABLE) {
2237		printf("\taddi.%d\t\tv%d,vFP,$%lld\n", bits_in_pointer, new->pseudo, 0LL);
2238		return new;
2239	}
2240	printf("\taddi.%d\t\tv%d,vFP,$offsetof(%s:%p)\n", bits_in_pointer, new->pseudo, show_ident(sym->ident), sym);
2241	return new;
2242}
2243
2244static void x86_symbol_init(struct symbol *sym)
2245{
2246	struct symbol_private *priv = sym->aux;
2247	struct expression *expr = sym->initializer;
2248	struct storage *new;
2249
2250	if (expr)
2251		new = x86_expression(expr);
2252	else
2253		new = stack_alloc(sym->bit_size / 8);
2254
2255	if (!priv) {
2256		priv = calloc(1, sizeof(*priv));
2257		sym->aux = priv;
2258		/* FIXME: leak! we don't free... */
2259		/* (well, we don't free symbols either) */
2260	}
2261
2262	priv->addr = new;
2263}
2264
2265static struct storage *x86_label_expr(struct expression *expr)
2266{
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);
2269	return new;
2270}
2271
2272static struct storage *x86_statement_expr(struct expression *expr)
2273{
2274	return x86_statement(expr->statement);
2275}
2276
2277static int x86_position_expr(struct expression *expr, struct symbol *base)
2278{
2279	struct storage *new = x86_expression(expr->init_expr);
2280	struct symbol *ctype = expr->init_expr->ctype;
2281
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));
2285	return 0;
2286}
2287
2288static void x86_initializer_expr(struct expression *expr, struct symbol *ctype)
2289{
2290	struct expression *entry;
2291
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);
2297			continue;
2298		}
2299
2300		// Ignore initializer indexes and identifiers - the
2301		// evaluator has taken them into account
2302		if (entry->type == EXPR_IDENTIFIER || entry->type == EXPR_INDEX)
2303			continue;
2304		if (entry->type == EXPR_POS) {
2305			x86_position_expr(entry, ctype);
2306			continue;
2307		}
2308		x86_initialization(ctype, entry);
2309	} END_FOR_EACH_PTR(entry);
2310}
2311
2312/*
2313 * Print out an expression. Return the pseudo that contains the
2314 * variable.
2315 */
2316static struct storage *x86_expression(struct expression *expr)
2317{
2318	if (!expr)
2319		return NULL;
2320
2321	if (!expr->ctype) {
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);
2326		return NULL;
2327	}
2328
2329	switch (expr->type) {
2330	default:
2331		return NULL;
2332	case EXPR_CALL:
2333		return x86_call_expression(expr);
2334
2335	case EXPR_ASSIGNMENT:
2336		return x86_assignment(expr);
2337
2338	case EXPR_COMPARE:
2339		return emit_compare(expr);
2340	case EXPR_BINOP:
2341	case EXPR_COMMA:
2342	case EXPR_LOGICAL:
2343		return emit_binop(expr);
2344	case EXPR_PREOP:
2345		return x86_preop(expr);
2346	case EXPR_POSTOP:
2347		return emit_postop(expr);
2348	case EXPR_SYMBOL:
2349		return emit_symbol_expr_init(expr->symbol);
2350	case EXPR_DEREF:
2351	case EXPR_SIZEOF:
2352	case EXPR_ALIGNOF:
2353		warning(expr->pos, "invalid expression after evaluation");
2354		return NULL;
2355	case EXPR_CAST:
2356	case EXPR_FORCE_CAST:
2357	case EXPR_IMPLIED_CAST:
2358		return emit_cast_expr(expr);
2359	case EXPR_VALUE:
2360		return emit_value(expr);
2361	case EXPR_STRING:
2362		return emit_string_expr(expr);
2363	case EXPR_INITIALIZER:
2364		x86_initializer_expr(expr, expr->ctype);
2365		return NULL;
2366	case EXPR_SELECT:
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);
2372	case EXPR_LABEL:
2373		return x86_label_expr(expr);
2374
2375	// None of these should exist as direct expressions: they are only
2376	// valid as sub-expressions of initializers.
2377	case EXPR_POS:
2378		warning(expr->pos, "unable to show plain initializer position expression");
2379		return NULL;
2380	case EXPR_IDENTIFIER:
2381		warning(expr->pos, "unable to show identifier expression");
2382		return NULL;
2383	case EXPR_INDEX:
2384		warning(expr->pos, "unable to show index expression");
2385		return NULL;
2386	case EXPR_TYPE:
2387		warning(expr->pos, "unable to show type expression");
2388		return NULL;
2389	case EXPR_FVALUE:
2390		warning(expr->pos, "floating point support is not implemented");
2391		return NULL;
2392	}
2393	return NULL;
2394}
2395