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