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 struct storage *x86_address_gen(struct expression *expr);
197 static struct storage *x86_symbol_expr(struct symbol *sym);
198 static void x86_symbol(struct symbol *sym);
199 static struct storage *x86_statement(struct statement *stmt);
200 static struct storage *x86_expression(struct expression *expr);
201 
202 enum registers {
203 	NOREG,
204 	 AL,  DL,  CL,  BL,  AH,  DH,  CH,  BH,	// 8-bit
205 	 AX,  DX,  CX,  BX,  SI,  DI,  BP,  SP,	// 16-bit
206 	EAX, EDX, ECX, EBX, ESI, EDI, EBP, ESP,	// 32-bit
207 	EAX_EDX, ECX_EBX, ESI_EDI,		// 64-bit
208 };
209 
210 /* This works on regno's, reg_info's and hardreg_storage's */
211 #define byte_reg(reg) ((reg) - 16)
212 #define highbyte_reg(reg) ((reg)-12)
213 #define word_reg(reg) ((reg)-8)
214 
215 #define REGINFO(nr, str, conflicts...)	[nr] = { .name = str, .aliases = { nr , conflicts } }
216 
217 static struct reg_info reg_info_table[] = {
218 	REGINFO( AL,  "%al", AX, EAX, EAX_EDX),
219 	REGINFO( DL,  "%dl", DX, EDX, EAX_EDX),
220 	REGINFO( CL,  "%cl", CX, ECX, ECX_EBX),
221 	REGINFO( BL,  "%bl", BX, EBX, ECX_EBX),
222 	REGINFO( AH,  "%ah", AX, EAX, EAX_EDX),
223 	REGINFO( DH,  "%dh", DX, EDX, EAX_EDX),
224 	REGINFO( CH,  "%ch", CX, ECX, ECX_EBX),
225 	REGINFO( BH,  "%bh", BX, EBX, ECX_EBX),
226 	REGINFO( AX,  "%ax", AL, AH, EAX, EAX_EDX),
227 	REGINFO( DX,  "%dx", DL, DH, EDX, EAX_EDX),
228 	REGINFO( CX,  "%cx", CL, CH, ECX, ECX_EBX),
229 	REGINFO( BX,  "%bx", BL, BH, EBX, ECX_EBX),
230 	REGINFO( SI,  "%si", ESI, ESI_EDI),
231 	REGINFO( DI,  "%di", EDI, ESI_EDI),
232 	REGINFO( BP,  "%bp", EBP),
233 	REGINFO( SP,  "%sp", ESP),
234 	REGINFO(EAX, "%eax", AL, AH, AX, EAX_EDX),
235 	REGINFO(EDX, "%edx", DL, DH, DX, EAX_EDX),
236 	REGINFO(ECX, "%ecx", CL, CH, CX, ECX_EBX),
237 	REGINFO(EBX, "%ebx", BL, BH, BX, ECX_EBX),
238 	REGINFO(ESI, "%esi", SI, ESI_EDI),
239 	REGINFO(EDI, "%edi", DI, ESI_EDI),
240 	REGINFO(EBP, "%ebp", BP),
241 	REGINFO(ESP, "%esp", SP),
242 	REGINFO(EAX_EDX, "%eax:%edx", AL, AH, AX, EAX, DL, DH, DX, EDX),
243 	REGINFO(ECX_EBX, "%ecx:%ebx", CL, CH, CX, ECX, BL, BH, BX, EBX),
244 	REGINFO(ESI_EDI, "%esi:%edi", SI, ESI, DI, EDI),
245 };
246 
247 #define REGSTORAGE(nr) [nr] = { .type = STOR_REG, .reg = reg_info_table + (nr) }
248 
249 static struct storage hardreg_storage_table[] = {
250 	REGSTORAGE(AL), REGSTORAGE(DL), REGSTORAGE(CL), REGSTORAGE(BL),
251 	REGSTORAGE(AH), REGSTORAGE(DH), REGSTORAGE(CH), REGSTORAGE(BH),
252 	REGSTORAGE(AX), REGSTORAGE(DX), REGSTORAGE(CX), REGSTORAGE(BX),
253 	REGSTORAGE(SI), REGSTORAGE(DI), REGSTORAGE(BP), REGSTORAGE(SP),
254 	REGSTORAGE(EAX), REGSTORAGE(EDX), REGSTORAGE(ECX), REGSTORAGE(EBX),
255 	REGSTORAGE(ESI), REGSTORAGE(EDI), REGSTORAGE(EBP), REGSTORAGE(ESP),
256 	REGSTORAGE(EAX_EDX), REGSTORAGE(ECX_EBX), REGSTORAGE(ESI_EDI),
257 };
258 
259 #define REG_EAX (&hardreg_storage_table[EAX])
260 #define REG_ECX (&hardreg_storage_table[ECX])
261 #define REG_EDX (&hardreg_storage_table[EDX])
262 #define REG_ESP (&hardreg_storage_table[ESP])
263 #define REG_DL	(&hardreg_storage_table[DL])
264 #define REG_DX	(&hardreg_storage_table[DX])
265 #define REG_AL	(&hardreg_storage_table[AL])
266 #define REG_AX	(&hardreg_storage_table[AX])
267 
268 static DECLARE_BITMAP(regs_in_use, 256);
269 
reginfo_reg(struct reg_info * info)270 static inline struct storage * reginfo_reg(struct reg_info *info)
271 {
272 	return hardreg_storage_table + info->own_regno;
273 }
274 
get_hardreg(struct storage * reg,int clear)275 static struct storage * get_hardreg(struct storage *reg, int clear)
276 {
277 	struct reg_info *info = reg->reg;
278 	const unsigned char *aliases;
279 	int regno;
280 
281 	aliases = info->aliases;
282 	while ((regno = *aliases++) != NOREG) {
283 		if (test_bit(regno, regs_in_use))
284 			goto busy;
285 		if (clear)
286 			reg_info_table[regno].contains = NULL;
287 	}
288 	set_bit(info->own_regno, regs_in_use);
289 	return reg;
290 busy:
291 	fprintf(stderr, "register %s is busy\n", info->name);
292 	if (regno + reg_info_table != info)
293 		fprintf(stderr, "  conflicts with %s\n", reg_info_table[regno].name);
294 	exit(1);
295 }
296 
put_reg(struct storage * reg)297 static void put_reg(struct storage *reg)
298 {
299 	struct reg_info *info = reg->reg;
300 	int regno = info->own_regno;
301 
302 	if (test_and_clear_bit(regno, regs_in_use))
303 		return;
304 	fprintf(stderr, "freeing already free'd register %s\n", reg_info_table[regno].name);
305 }
306 
307 struct regclass {
308 	const char *name;
309 	const unsigned char regs[30];
310 };
311 
312 static struct regclass regclass_8 = { "8-bit", { AL, DL, CL, BL, AH, DH, CH, BH }};
313 static struct regclass regclass_16 = { "16-bit", { AX, DX, CX, BX, SI, DI, BP }};
314 static struct regclass regclass_32 = { "32-bit", { EAX, EDX, ECX, EBX, ESI, EDI, EBP }};
315 static struct regclass regclass_64 = { "64-bit", { EAX_EDX, ECX_EBX, ESI_EDI }};
316 
317 static struct regclass regclass_32_8 = { "32-bit bytes", { EAX, EDX, ECX, EBX }};
318 
get_regclass_bits(int bits)319 static struct regclass *get_regclass_bits(int bits)
320 {
321 	switch (bits) {
322 	case 8: return &regclass_8;
323 	case 16: return &regclass_16;
324 	case 64: return &regclass_64;
325 	default: return &regclass_32;
326 	}
327 }
328 
get_regclass(struct expression * expr)329 static struct regclass *get_regclass(struct expression *expr)
330 {
331 	return get_regclass_bits(expr->ctype->bit_size);
332 }
333 
register_busy(int regno)334 static int register_busy(int regno)
335 {
336 	if (!test_bit(regno, regs_in_use)) {
337 		struct reg_info *info = reg_info_table + regno;
338 		const unsigned char *regs = info->aliases+1;
339 
340 		while ((regno = *regs) != NOREG) {
341 			regs++;
342 			if (test_bit(regno, regs_in_use))
343 				goto busy;
344 		}
345 		return 0;
346 	}
347 busy:
348 	return 1;
349 }
350 
get_reg(struct regclass * class)351 static struct storage *get_reg(struct regclass *class)
352 {
353 	const unsigned char *regs = class->regs;
354 	int regno;
355 
356 	while ((regno = *regs) != NOREG) {
357 		regs++;
358 		if (register_busy(regno))
359 			continue;
360 		return get_hardreg(hardreg_storage_table + regno, 1);
361 	}
362 	fprintf(stderr, "Ran out of %s registers\n", class->name);
363 	exit(1);
364 }
365 
get_reg_value(struct storage * value,struct regclass * class)366 static struct storage *get_reg_value(struct storage *value, struct regclass *class)
367 {
368 	struct reg_info *info;
369 	struct storage *reg;
370 
371 	/* Do we already have it somewhere */
372 	info = value->reg;
373 	if (info && info->contains == value) {
374 		emit_comment("already have register %s", info->name);
375 		return get_hardreg(hardreg_storage_table + info->own_regno, 0);
376 	}
377 
378 	reg = get_reg(class);
379 	emit_move(value, reg, value->ctype, "reload register");
380 	info = reg->reg;
381 	info->contains = value;
382 	value->reg = info;
383 	return reg;
384 }
385 
temp_from_bits(unsigned int bit_size)386 static struct storage *temp_from_bits(unsigned int bit_size)
387 {
388 	return get_reg(get_regclass_bits(bit_size));
389 }
390 
pseudo_offset(struct storage * s)391 static inline unsigned int pseudo_offset(struct storage *s)
392 {
393 	if (s->type != STOR_PSEUDO)
394 		return 123456;	/* intentionally bogus value */
395 
396 	return s->offset;
397 }
398 
arg_offset(struct storage * s)399 static inline unsigned int arg_offset(struct storage *s)
400 {
401 	if (s->type != STOR_ARG)
402 		return 123456;	/* intentionally bogus value */
403 
404 	/* FIXME: this is wrong wrong wrong */
405 	return current_func->stack_size + ((1 + s->idx) * 4);
406 }
407 
pretty_offset(int ofs)408 static const char *pretty_offset(int ofs)
409 {
410 	static char esp_buf[64];
411 
412 	if (ofs)
413 		sprintf(esp_buf, "%d(%%esp)", ofs);
414 	else
415 		strcpy(esp_buf, "(%esp)");
416 
417 	return esp_buf;
418 }
419 
stor_sym_init(struct symbol * sym)420 static void stor_sym_init(struct symbol *sym)
421 {
422 	struct storage *stor;
423 	struct symbol_private *priv;
424 
425 	priv = calloc(1, sizeof(*priv) + sizeof(*stor));
426 	if (!priv)
427 		die("OOM in stor_sym_init");
428 
429 	stor = (struct storage *) (priv + 1);
430 
431 	priv->addr = stor;
432 	stor->type = STOR_SYM;
433 	stor->sym = sym;
434 }
435 
stor_op_name(struct storage * s)436 static const char *stor_op_name(struct storage *s)
437 {
438 	static char name[32];
439 
440 	switch (s->type) {
441 	case STOR_PSEUDO:
442 		strcpy(name, pretty_offset((int) pseudo_offset(s)));
443 		break;
444 	case STOR_ARG:
445 		strcpy(name, pretty_offset((int) arg_offset(s)));
446 		break;
447 	case STOR_SYM:
448 		strcpy(name, show_ident(s->sym->ident));
449 		break;
450 	case STOR_REG:
451 		strcpy(name, s->reg->name);
452 		break;
453 	case STOR_VALUE:
454 		sprintf(name, "$%lld", s->value);
455 		break;
456 	case STOR_LABEL:
457 		sprintf(name, "%s.L%d", s->flags & STOR_LABEL_VAL ? "$" : "",
458 			s->label);
459 		break;
460 	case STOR_LABELSYM:
461 		sprintf(name, "%s.LS%p", s->flags & STOR_LABEL_VAL ? "$" : "",
462 			s->labelsym);
463 		break;
464 	}
465 
466 	return name;
467 }
468 
new_atom(enum atom_type type)469 static struct atom *new_atom(enum atom_type type)
470 {
471 	struct atom *atom;
472 
473 	atom = calloc(1, sizeof(*atom));	/* TODO: chunked alloc */
474 	if (!atom)
475 		die("nuclear OOM");
476 
477 	atom->type = type;
478 
479 	return atom;
480 }
481 
push_cstring(struct function * f,struct string * str,int label)482 static inline void push_cstring(struct function *f, struct string *str,
483 				int label)
484 {
485 	struct atom *atom;
486 
487 	atom = new_atom(ATOM_CSTR);
488 	atom->string = str;
489 	atom->label = label;
490 
491 	add_ptr_list(&f->str_list, atom);	/* note: _not_ atom_list */
492 }
493 
push_atom(struct function * f,struct atom * atom)494 static inline void push_atom(struct function *f, struct atom *atom)
495 {
496 	add_ptr_list(&f->atom_list, atom);
497 }
498 
push_text_atom(struct function * f,const char * text)499 static void push_text_atom(struct function *f, const char *text)
500 {
501 	struct atom *atom = new_atom(ATOM_TEXT);
502 
503 	atom->text = strdup(text);
504 	atom->text_len = strlen(text);
505 
506 	push_atom(f, atom);
507 }
508 
new_storage(enum storage_type type)509 static struct storage *new_storage(enum storage_type type)
510 {
511 	struct storage *stor;
512 
513 	stor = calloc(1, sizeof(*stor));
514 	if (!stor)
515 		die("OOM in new_storage");
516 
517 	stor->type = type;
518 
519 	return stor;
520 }
521 
stack_alloc(int n_bytes)522 static struct storage *stack_alloc(int n_bytes)
523 {
524 	struct function *f = current_func;
525 	struct storage *stor;
526 
527 	assert(f != NULL);
528 
529 	stor = new_storage(STOR_PSEUDO);
530 	stor->type = STOR_PSEUDO;
531 	stor->pseudo = f->pseudo_nr;
532 	stor->offset = f->stack_size; /* FIXME: stack req. natural align */
533 	stor->size = n_bytes;
534 	f->stack_size += n_bytes;
535 	f->pseudo_nr++;
536 
537 	add_ptr_list(&f->pseudo_list, stor);
538 
539 	return stor;
540 }
541 
new_labelsym(struct symbol * sym)542 static struct storage *new_labelsym(struct symbol *sym)
543 {
544 	struct storage *stor;
545 
546 	stor = new_storage(STOR_LABELSYM);
547 
548 	if (stor) {
549 		stor->flags |= STOR_WANTS_FREE;
550 		stor->labelsym = sym;
551 	}
552 
553 	return stor;
554 }
555 
new_val(long long value)556 static struct storage *new_val(long long value)
557 {
558 	struct storage *stor;
559 
560 	stor = new_storage(STOR_VALUE);
561 
562 	if (stor) {
563 		stor->flags |= STOR_WANTS_FREE;
564 		stor->value = value;
565 	}
566 
567 	return stor;
568 }
569 
new_label(void)570 static int new_label(void)
571 {
572 	static int label = 0;
573 	return ++label;
574 }
575 
textbuf_push(struct textbuf ** buf_p,const char * text)576 static void textbuf_push(struct textbuf **buf_p, const char *text)
577 {
578 	struct textbuf *tmp, *list = *buf_p;
579 	unsigned int text_len = strlen(text);
580 	unsigned int alloc_len = text_len + 1 + sizeof(*list);
581 
582 	tmp = calloc(1, alloc_len);
583 	if (!tmp)
584 		die("OOM on textbuf alloc");
585 
586 	tmp->text = ((void *) tmp) + sizeof(*tmp);
587 	memcpy(tmp->text, text, text_len + 1);
588 	tmp->len = text_len;
589 
590 	/* add to end of list */
591 	if (!list) {
592 		list = tmp;
593 		tmp->prev = tmp;
594 	} else {
595 		tmp->prev = list->prev;
596 		tmp->prev->next = tmp;
597 		list->prev = tmp;
598 	}
599 	tmp->next = list;
600 
601 	*buf_p = list;
602 }
603 
textbuf_emit(struct textbuf ** buf_p)604 static void textbuf_emit(struct textbuf **buf_p)
605 {
606 	struct textbuf *tmp, *list = *buf_p;
607 
608 	while (list) {
609 		tmp = list;
610 		if (tmp->next == tmp)
611 			list = NULL;
612 		else {
613 			tmp->prev->next = tmp->next;
614 			tmp->next->prev = tmp->prev;
615 			list = tmp->next;
616 		}
617 
618 		fputs(tmp->text, stdout);
619 
620 		free(tmp);
621 	}
622 
623 	*buf_p = list;
624 }
625 
insn(const char * insn,struct storage * op1,struct storage * op2,const char * comment_in)626 static void insn(const char *insn, struct storage *op1, struct storage *op2,
627 		 const char *comment_in)
628 {
629 	struct function *f = current_func;
630 	struct atom *atom = new_atom(ATOM_INSN);
631 
632 	assert(insn != NULL);
633 
634 	strcpy(atom->insn, insn);
635 	if (comment_in && (*comment_in))
636 		strncpy(atom->comment, comment_in,
637 			sizeof(atom->comment) - 1);
638 
639 	atom->op1 = op1;
640 	atom->op2 = op2;
641 
642 	push_atom(f, atom);
643 }
644 
emit_comment(const char * fmt,...)645 static void emit_comment(const char *fmt, ...)
646 {
647 	struct function *f = current_func;
648 	static char tmpbuf[100] = "\t# ";
649 	va_list args;
650 	int i;
651 
652 	va_start(args, fmt);
653 	i = vsnprintf(tmpbuf+3, sizeof(tmpbuf)-4, fmt, args);
654 	va_end(args);
655 	tmpbuf[i+3] = '\n';
656 	tmpbuf[i+4] = '\0';
657 	push_text_atom(f, tmpbuf);
658 }
659 
emit_label(int label,const char * comment)660 static void emit_label (int label, const char *comment)
661 {
662 	struct function *f = current_func;
663 	char s[64];
664 
665 	if (!comment)
666 		sprintf(s, ".L%d:\n", label);
667 	else
668 		sprintf(s, ".L%d:\t\t\t\t\t# %s\n", label, comment);
669 
670 	push_text_atom(f, s);
671 }
672 
emit_labelsym(struct symbol * sym,const char * comment)673 static void emit_labelsym (struct symbol *sym, const char *comment)
674 {
675 	struct function *f = current_func;
676 	char s[64];
677 
678 	if (!comment)
679 		sprintf(s, ".LS%p:\n", sym);
680 	else
681 		sprintf(s, ".LS%p:\t\t\t\t# %s\n", sym, comment);
682 
683 	push_text_atom(f, s);
684 }
685 
emit_unit_begin(const char * basename)686 void emit_unit_begin(const char *basename)
687 {
688 	printf("\t.file\t\"%s\"\n", basename);
689 }
690 
emit_unit_end(void)691 void emit_unit_end(void)
692 {
693 	textbuf_emit(&unit_post_text);
694 	printf("\t.ident\t\"sparse silly x86 backend (version %s)\"\n", SPARSE_VERSION);
695 }
696 
697 /* conditionally switch sections */
emit_section(const char * s)698 static void emit_section(const char *s)
699 {
700 	if (s == current_section)
701 		return;
702 	if (current_section && (!strcmp(s, current_section)))
703 		return;
704 
705 	printf("\t%s\n", s);
706 	current_section = s;
707 }
708 
emit_insn_atom(struct function * f,struct atom * atom)709 static void emit_insn_atom(struct function *f, struct atom *atom)
710 {
711 	char s[128];
712 	char comment[64];
713 	struct storage *op1 = atom->op1;
714 	struct storage *op2 = atom->op2;
715 
716 	if (atom->comment[0])
717 		sprintf(comment, "\t\t# %s", atom->comment);
718 	else
719 		comment[0] = 0;
720 
721 	if (atom->op2) {
722 		char tmp[16];
723 		strcpy(tmp, stor_op_name(op1));
724 		sprintf(s, "\t%s\t%s, %s%s\n",
725 			atom->insn, tmp, stor_op_name(op2), comment);
726 	} else if (atom->op1)
727 		sprintf(s, "\t%s\t%s%s%s\n",
728 			atom->insn, stor_op_name(op1),
729 			comment[0] ? "\t" : "", comment);
730 	else
731 		sprintf(s, "\t%s\t%s%s\n",
732 			atom->insn,
733 			comment[0] ? "\t\t" : "", comment);
734 
735 	if (write(STDOUT_FILENO, s, strlen(s)) < 0)
736 		die("can't write to stdout");
737 }
738 
emit_atom_list(struct function * f)739 static void emit_atom_list(struct function *f)
740 {
741 	struct atom *atom;
742 
743 	FOR_EACH_PTR(f->atom_list, atom) {
744 		switch (atom->type) {
745 		case ATOM_TEXT: {
746 			if (write(STDOUT_FILENO, atom->text, atom->text_len) < 0)
747 				die("can't write to stdout");
748 			break;
749 		}
750 		case ATOM_INSN:
751 			emit_insn_atom(f, atom);
752 			break;
753 		case ATOM_CSTR:
754 			assert(0);
755 			break;
756 		}
757 	} END_FOR_EACH_PTR(atom);
758 }
759 
emit_string_list(struct function * f)760 static void emit_string_list(struct function *f)
761 {
762 	struct atom *atom;
763 
764 	emit_section(".section\t.rodata");
765 
766 	FOR_EACH_PTR(f->str_list, atom) {
767 		/* FIXME: escape " in string */
768 		printf(".L%d:\n", atom->label);
769 		printf("\t.string\t%s\n", show_string(atom->string));
770 
771 		free(atom);
772 	} END_FOR_EACH_PTR(atom);
773 }
774 
func_cleanup(struct function * f)775 static void func_cleanup(struct function *f)
776 {
777 	struct storage *stor;
778 	struct atom *atom;
779 
780 	FOR_EACH_PTR(f->atom_list, atom) {
781 		if ((atom->type == ATOM_TEXT) && (atom->text))
782 			free(atom->text);
783 		if (atom->op1 && (atom->op1->flags & STOR_WANTS_FREE))
784 			free(atom->op1);
785 		if (atom->op2 && (atom->op2->flags & STOR_WANTS_FREE))
786 			free(atom->op2);
787 		free(atom);
788 	} END_FOR_EACH_PTR(atom);
789 
790 	FOR_EACH_PTR(f->pseudo_list, stor) {
791 		free(stor);
792 	} END_FOR_EACH_PTR(stor);
793 
794 	free_ptr_list(&f->pseudo_list);
795 	free(f);
796 }
797 
798 /* function prologue */
emit_func_pre(struct symbol * sym)799 static void emit_func_pre(struct symbol *sym)
800 {
801 	struct function *f;
802 	struct symbol *arg;
803 	unsigned int i, argc = 0, alloc_len;
804 	unsigned char *mem;
805 	struct symbol_private *privbase;
806 	struct storage *storage_base;
807 	struct symbol *base_type = sym->ctype.base_type;
808 
809 	FOR_EACH_PTR(base_type->arguments, arg) {
810 		argc++;
811 	} END_FOR_EACH_PTR(arg);
812 
813 	alloc_len =
814 		sizeof(*f) +
815 		(argc * sizeof(struct symbol *)) +
816 		(argc * sizeof(struct symbol_private)) +
817 		(argc * sizeof(struct storage));
818 	mem = calloc(1, alloc_len);
819 	if (!mem)
820 		die("OOM on func info");
821 
822 	f		=  (struct function *) mem;
823 	mem		+= sizeof(*f);
824 	f->argv		=  (struct symbol **) mem;
825 	mem		+= (argc * sizeof(struct symbol *));
826 	privbase	=  (struct symbol_private *) mem;
827 	mem		+= (argc * sizeof(struct symbol_private));
828 	storage_base	=  (struct storage *) mem;
829 
830 	f->argc = argc;
831 	f->ret_target = new_label();
832 
833 	i = 0;
834 	FOR_EACH_PTR(base_type->arguments, arg) {
835 		f->argv[i] = arg;
836 		arg->aux = &privbase[i];
837 		storage_base[i].type = STOR_ARG;
838 		storage_base[i].idx = i;
839 		privbase[i].addr = &storage_base[i];
840 		i++;
841 	} END_FOR_EACH_PTR(arg);
842 
843 	assert(current_func == NULL);
844 	current_func = f;
845 }
846 
847 /* function epilogue */
emit_func_post(struct symbol * sym)848 static void emit_func_post(struct symbol *sym)
849 {
850 	const char *name = show_ident(sym->ident);
851 	struct function *f = current_func;
852 	int stack_size = f->stack_size;
853 
854 	if (f->str_list)
855 		emit_string_list(f);
856 
857 	/* function prologue */
858 	emit_section(".text");
859 	if ((sym->ctype.modifiers & MOD_STATIC) == 0)
860 		printf(".globl %s\n", name);
861 	printf("\t.type\t%s, @function\n", name);
862 	printf("%s:\n", name);
863 
864 	if (stack_size) {
865 		char pseudo_const[16];
866 
867 		sprintf(pseudo_const, "$%d", stack_size);
868 		printf("\tsubl\t%s, %%esp\n", pseudo_const);
869 	}
870 
871 	/* function epilogue */
872 
873 	/* jump target for 'return' statements */
874 	emit_label(f->ret_target, NULL);
875 
876 	if (stack_size) {
877 		struct storage *val;
878 
879 		val = new_storage(STOR_VALUE);
880 		val->value = (long long) (stack_size);
881 		val->flags = STOR_WANTS_FREE;
882 
883 		insn("addl", val, REG_ESP, NULL);
884 	}
885 
886 	insn("ret", NULL, NULL, NULL);
887 
888 	/* output everything to stdout */
889 	fflush(stdout);		/* paranoia; needed? */
890 	emit_atom_list(f);
891 
892 	/* function footer */
893 	name = show_ident(sym->ident);
894 	printf("\t.size\t%s, .-%s\n", name, name);
895 
896 	func_cleanup(f);
897 	current_func = NULL;
898 }
899 
900 /* emit object (a.k.a. variable, a.k.a. data) prologue */
emit_object_pre(const char * name,unsigned long modifiers,unsigned long alignment,unsigned int byte_size)901 static void emit_object_pre(const char *name, unsigned long modifiers,
902 			    unsigned long alignment, unsigned int byte_size)
903 {
904 	if ((modifiers & MOD_STATIC) == 0)
905 		printf(".globl %s\n", name);
906 	emit_section(".data");
907 	if (alignment)
908 		printf("\t.align %lu\n", alignment);
909 	printf("\t.type\t%s, @object\n", name);
910 	printf("\t.size\t%s, %d\n", name, byte_size);
911 	printf("%s:\n", name);
912 }
913 
914 /* emit value (only) for an initializer scalar */
emit_scalar(struct expression * expr,unsigned int bit_size)915 static void emit_scalar(struct expression *expr, unsigned int bit_size)
916 {
917 	const char *type;
918 	long long ll;
919 
920 	assert(expr->type == EXPR_VALUE);
921 
922 	if (expr->value == 0ULL) {
923 		printf("\t.zero\t%d\n", bit_size / 8);
924 		return;
925 	}
926 
927 	ll = (long long) expr->value;
928 
929 	switch (bit_size) {
930 	case 8:		type = "byte";	ll = (char) ll; break;
931 	case 16:	type = "value";	ll = (short) ll; break;
932 	case 32:	type = "long";	ll = (int) ll; break;
933 	case 64:	type = "quad";	break;
934 	default:	type = NULL;	break;
935 	}
936 
937 	assert(type != NULL);
938 
939 	printf("\t.%s\t%lld\n", type, ll);
940 }
941 
emit_global_noinit(const char * name,unsigned long modifiers,unsigned long alignment,unsigned int byte_size)942 static void emit_global_noinit(const char *name, unsigned long modifiers,
943 			       unsigned long alignment, unsigned int byte_size)
944 {
945 	char s[64];
946 
947 	if (modifiers & MOD_STATIC) {
948 		sprintf(s, "\t.local\t%s\n", name);
949 		textbuf_push(&unit_post_text, s);
950 	}
951 	if (alignment)
952 		sprintf(s, "\t.comm\t%s,%d,%lu\n", name, byte_size, alignment);
953 	else
954 		sprintf(s, "\t.comm\t%s,%d\n", name, byte_size);
955 	textbuf_push(&unit_post_text, s);
956 }
957 
958 static int ea_current, ea_last;
959 
emit_initializer(struct symbol * sym,struct expression * expr)960 static void emit_initializer(struct symbol *sym,
961 			     struct expression *expr)
962 {
963 	int distance = ea_current - ea_last - 1;
964 
965 	if (distance > 0)
966 		printf("\t.zero\t%d\n", (sym->bit_size / 8) * distance);
967 
968 	if (expr->type == EXPR_VALUE) {
969 		struct symbol *base_type = sym->ctype.base_type;
970 		assert(base_type != NULL);
971 
972 		emit_scalar(expr, sym->bit_size / get_expression_value(base_type->array_size));
973 		return;
974 	}
975 	if (expr->type != EXPR_INITIALIZER)
976 		return;
977 
978 	assert(0); /* FIXME */
979 }
980 
sort_array_cmp(const struct expression * a,const struct expression * b)981 static int sort_array_cmp(const struct expression *a,
982 			  const struct expression *b)
983 {
984 	int a_ofs = 0, b_ofs = 0;
985 
986 	if (a->type == EXPR_POS)
987 		a_ofs = (int) a->init_offset;
988 	if (b->type == EXPR_POS)
989 		b_ofs = (int) b->init_offset;
990 
991 	return a_ofs - b_ofs;
992 }
993 
994 /* move to front-end? */
sort_array(struct expression * expr)995 static void sort_array(struct expression *expr)
996 {
997 	struct expression *entry, **list;
998 	unsigned int elem, sorted, i;
999 
1000 	elem = expression_list_size(expr->expr_list);
1001 	if (!elem)
1002 		return;
1003 
1004 	list = malloc(sizeof(entry) * elem);
1005 	if (!list)
1006 		die("OOM in sort_array");
1007 
1008 	/* this code is no doubt evil and ignores EXPR_INDEX possibly
1009 	 * to its detriment and other nasty things.  improvements
1010 	 * welcome.
1011 	 */
1012 	i = 0;
1013 	sorted = 0;
1014 	FOR_EACH_PTR(expr->expr_list, entry) {
1015 		if ((entry->type == EXPR_POS) || (entry->type == EXPR_VALUE)) {
1016 			/* add entry to list[], in sorted order */
1017 			if (sorted == 0) {
1018 				list[0] = entry;
1019 				sorted = 1;
1020 			} else {
1021 				for (i = 0; i < sorted; i++)
1022 					if (sort_array_cmp(entry, list[i]) <= 0)
1023 						break;
1024 
1025 				/* If inserting into the middle of list[]
1026 				 * instead of appending, we memmove.
1027 				 * This is ugly, but thankfully
1028 				 * uncommon.  Input data with tons of
1029 				 * entries very rarely have explicit
1030 				 * offsets.  convert to qsort eventually...
1031 				 */
1032 				if (i != sorted)
1033 					memmove(&list[i + 1], &list[i],
1034 						(sorted - i) * sizeof(entry));
1035 				list[i] = entry;
1036 				sorted++;
1037 			}
1038 		}
1039 	} END_FOR_EACH_PTR(entry);
1040 
1041 	i = 0;
1042 	FOR_EACH_PTR(expr->expr_list, entry) {
1043 		if ((entry->type == EXPR_POS) || (entry->type == EXPR_VALUE))
1044 			*THIS_ADDRESS(entry) = list[i++];
1045 	} END_FOR_EACH_PTR(entry);
1046 
1047 	free(list);
1048 }
1049 
emit_array(struct symbol * sym)1050 static void emit_array(struct symbol *sym)
1051 {
1052 	struct symbol *base_type = sym->ctype.base_type;
1053 	struct expression *expr = sym->initializer;
1054 	struct expression *entry;
1055 
1056 	assert(base_type != NULL);
1057 
1058 	stor_sym_init(sym);
1059 
1060 	ea_last = -1;
1061 
1062 	emit_object_pre(show_ident(sym->ident), sym->ctype.modifiers,
1063 		        sym->ctype.alignment,
1064 			sym->bit_size / 8);
1065 
1066 	sort_array(expr);
1067 
1068 	FOR_EACH_PTR(expr->expr_list, entry) {
1069 		if (entry->type == EXPR_VALUE) {
1070 			ea_current = 0;
1071 			emit_initializer(sym, entry);
1072 			ea_last = ea_current;
1073 		} else if (entry->type == EXPR_POS) {
1074 			ea_current =
1075 			    entry->init_offset / (base_type->bit_size / 8);
1076 			emit_initializer(sym, entry->init_expr);
1077 			ea_last = ea_current;
1078 		}
1079 	} END_FOR_EACH_PTR(entry);
1080 }
1081 
emit_one_symbol(struct symbol * sym)1082 void emit_one_symbol(struct symbol *sym)
1083 {
1084 	x86_symbol(sym);
1085 }
1086 
emit_copy(struct storage * dest,struct storage * src,struct symbol * ctype)1087 static void emit_copy(struct storage *dest, struct storage *src,
1088 		      struct symbol *ctype)
1089 {
1090 	struct storage *reg = NULL;
1091 	unsigned int bit_size;
1092 
1093 	/* FIXME: Bitfield copy! */
1094 
1095 	bit_size = src->size * 8;
1096 	if (!bit_size)
1097 		bit_size = 32;
1098 	if ((src->type == STOR_ARG) && (bit_size < 32))
1099 		bit_size = 32;
1100 
1101 	reg = temp_from_bits(bit_size);
1102 	emit_move(src, reg, ctype, "begin copy ..");
1103 
1104 	bit_size = dest->size * 8;
1105 	if (!bit_size)
1106 		bit_size = 32;
1107 	if ((dest->type == STOR_ARG) && (bit_size < 32))
1108 		bit_size = 32;
1109 
1110 	emit_move(reg, dest, ctype, ".... end copy");
1111 	put_reg(reg);
1112 }
1113 
emit_store(struct expression * dest_expr,struct storage * dest,struct storage * src,int bits)1114 static void emit_store(struct expression *dest_expr, struct storage *dest,
1115 		       struct storage *src, int bits)
1116 {
1117 	/* FIXME: Bitfield store! */
1118 	printf("\tst.%d\t\tv%d,[v%d]\n", bits, src->pseudo, dest->pseudo);
1119 }
1120 
emit_scalar_noinit(struct symbol * sym)1121 static void emit_scalar_noinit(struct symbol *sym)
1122 {
1123 	emit_global_noinit(show_ident(sym->ident),
1124 			   sym->ctype.modifiers, sym->ctype.alignment,
1125 			   sym->bit_size / 8);
1126 	stor_sym_init(sym);
1127 }
1128 
emit_array_noinit(struct symbol * sym)1129 static void emit_array_noinit(struct symbol *sym)
1130 {
1131 	emit_global_noinit(show_ident(sym->ident),
1132 			   sym->ctype.modifiers, sym->ctype.alignment,
1133 			   get_expression_value(sym->array_size) * (sym->bit_size / 8));
1134 	stor_sym_init(sym);
1135 }
1136 
opbits(const char * insn,unsigned int bits)1137 static const char *opbits(const char *insn, unsigned int bits)
1138 {
1139 	static char opbits_str[32];
1140 	char c;
1141 
1142 	switch (bits) {
1143 	case 8:	 c = 'b'; break;
1144 	case 16: c = 'w'; break;
1145 	case 32: c = 'l'; break;
1146 	case 64: c = 'q'; break;
1147 	default: abort(); break;
1148 	}
1149 
1150 	sprintf(opbits_str, "%s%c", insn, c);
1151 
1152 	return opbits_str;
1153 }
1154 
emit_move(struct storage * src,struct storage * dest,struct symbol * ctype,const char * comment)1155 static void emit_move(struct storage *src, struct storage *dest,
1156 		      struct symbol *ctype, const char *comment)
1157 {
1158 	unsigned int bits;
1159 	unsigned int is_signed;
1160 	unsigned int is_dest = (src->type == STOR_REG);
1161 	const char *opname;
1162 
1163 	if (ctype) {
1164 		bits = ctype->bit_size;
1165 		is_signed = is_signed_type(ctype);
1166 	} else {
1167 		bits = 32;
1168 		is_signed = 0;
1169 	}
1170 
1171 	/*
1172 	 * Are we moving from a register to a register?
1173 	 * Make the new reg to be the "cache".
1174 	 */
1175 	if ((dest->type == STOR_REG) && (src->type == STOR_REG)) {
1176 		struct storage *backing;
1177 
1178 reg_reg_move:
1179 		if (dest == src)
1180 			return;
1181 
1182 		backing = src->reg->contains;
1183 		if (backing) {
1184 			/* Is it still valid? */
1185 			if (backing->reg != src->reg)
1186 				backing = NULL;
1187 			else
1188 				backing->reg = dest->reg;
1189 		}
1190 		dest->reg->contains = backing;
1191 		insn("mov", src, dest, NULL);
1192 		return;
1193 	}
1194 
1195 	/*
1196 	 * Are we moving to a register from a non-reg?
1197 	 *
1198 	 * See if we have the non-reg source already cached
1199 	 * in a register..
1200 	 */
1201 	if (dest->type == STOR_REG) {
1202 		if (src->reg) {
1203 			struct reg_info *info = src->reg;
1204 			if (info->contains == src) {
1205 				src = reginfo_reg(info);
1206 				goto reg_reg_move;
1207 			}
1208 		}
1209 		dest->reg->contains = src;
1210 		src->reg = dest->reg;
1211 	}
1212 
1213 	if (src->type == STOR_REG) {
1214 		/* We could just mark the register dirty here and do lazy store.. */
1215 		src->reg->contains = dest;
1216 		dest->reg = src->reg;
1217 	}
1218 
1219 	if ((bits == 8) || (bits == 16)) {
1220 		if (is_dest)
1221 			opname = "mov";
1222 		else
1223 			opname = is_signed ? "movsx" : "movzx";
1224 	} else
1225 		opname = "mov";
1226 
1227 	insn(opbits(opname, bits), src, dest, comment);
1228 }
1229 
emit_compare(struct expression * expr)1230 static struct storage *emit_compare(struct expression *expr)
1231 {
1232 	struct storage *left = x86_expression(expr->left);
1233 	struct storage *right = x86_expression(expr->right);
1234 	struct storage *reg1, *reg2;
1235 	struct storage *new, *val;
1236 	const char *opname = NULL;
1237 	unsigned int right_bits = expr->right->ctype->bit_size;
1238 
1239 	switch(expr->op) {
1240 	case '<': 		opname = "setl";	break;
1241 	case '>':		opname = "setg";	break;
1242 	case SPECIAL_LTE:
1243 				opname = "setle";	break;
1244 	case SPECIAL_GTE:
1245 				opname = "setge";	break;
1246 	case SPECIAL_EQUAL:	opname = "sete";	break;
1247 	case SPECIAL_NOTEQUAL:	opname = "setne";	break;
1248 	case SPECIAL_UNSIGNED_LT:
1249 				opname = "setb";	break;
1250 	case SPECIAL_UNSIGNED_GT:
1251 				opname = "seta";	break;
1252 	case SPECIAL_UNSIGNED_LTE:
1253 				opname = "setb";	break;
1254 	case SPECIAL_UNSIGNED_GTE:
1255 				opname = "setae";	break;
1256 	default:
1257 		assert(0);
1258 		break;
1259 	}
1260 
1261 	/* init EDX to 0 */
1262 	val = new_storage(STOR_VALUE);
1263 	val->flags = STOR_WANTS_FREE;
1264 
1265 	reg1 = get_reg(&regclass_32_8);
1266 	emit_move(val, reg1, NULL, NULL);
1267 
1268 	/* move op1 into EAX */
1269 	reg2 = get_reg_value(left, get_regclass(expr->left));
1270 
1271 	/* perform comparison, RHS (op1, right) and LHS (op2, EAX) */
1272 	insn(opbits("cmp", right_bits), right, reg2, NULL);
1273 	put_reg(reg2);
1274 
1275 	/* store result of operation, 0 or 1, in DL using SETcc */
1276 	insn(opname, byte_reg(reg1), NULL, NULL);
1277 
1278 	/* finally, store the result (DL) in a new pseudo / stack slot */
1279 	new = stack_alloc(4);
1280 	emit_move(reg1, new, NULL, "end EXPR_COMPARE");
1281 	put_reg(reg1);
1282 
1283 	return new;
1284 }
1285 
emit_value(struct expression * expr)1286 static struct storage *emit_value(struct expression *expr)
1287 {
1288 #if 0 /* old and slow way */
1289 	struct storage *new = stack_alloc(4);
1290 	struct storage *val;
1291 
1292 	val = new_storage(STOR_VALUE);
1293 	val->value = (long long) expr->value;
1294 	val->flags = STOR_WANTS_FREE;
1295 	insn("movl", val, new, NULL);
1296 
1297 	return new;
1298 #else
1299 	struct storage *val;
1300 
1301 	val = new_storage(STOR_VALUE);
1302 	val->value = (long long) expr->value;
1303 
1304 	return val;	/* FIXME: memory leak */
1305 #endif
1306 }
1307 
emit_divide(struct expression * expr,struct storage * left,struct storage * right)1308 static struct storage *emit_divide(struct expression *expr, struct storage *left, struct storage *right)
1309 {
1310 	struct storage *eax_edx;
1311 	struct storage *reg, *new;
1312 	struct storage *val = new_storage(STOR_VALUE);
1313 
1314 	emit_comment("begin DIVIDE");
1315 	eax_edx = get_hardreg(hardreg_storage_table + EAX_EDX, 1);
1316 
1317 	/* init EDX to 0 */
1318 	val->flags = STOR_WANTS_FREE;
1319 	emit_move(val, REG_EDX, NULL, NULL);
1320 
1321 	new = stack_alloc(expr->ctype->bit_size / 8);
1322 
1323 	/* EAX is dividend */
1324 	emit_move(left, REG_EAX, NULL, NULL);
1325 
1326 	reg = get_reg_value(right, &regclass_32);
1327 
1328 	/* perform binop */
1329 	insn("div", reg, REG_EAX, NULL);
1330 	put_reg(reg);
1331 
1332 	reg = REG_EAX;
1333 	if (expr->op == '%')
1334 		reg = REG_EDX;
1335 	emit_move(reg, new, NULL, NULL);
1336 
1337 	put_reg(eax_edx);
1338 	emit_comment("end DIVIDE");
1339 	return new;
1340 }
1341 
emit_binop(struct expression * expr)1342 static struct storage *emit_binop(struct expression *expr)
1343 {
1344 	struct storage *left = x86_expression(expr->left);
1345 	struct storage *right = x86_expression(expr->right);
1346 	struct storage *new;
1347 	struct storage *dest, *src;
1348 	const char *opname = NULL;
1349 	const char *suffix = NULL;
1350 	char opstr[16];
1351 	int is_signed;
1352 
1353 	/* Divides have special register constraints */
1354 	if ((expr->op == '/') || (expr->op == '%'))
1355 		return emit_divide(expr, left, right);
1356 
1357 	is_signed = is_signed_type(expr->ctype);
1358 
1359 	switch (expr->op) {
1360 	case '+':
1361 		opname = "add";
1362 		break;
1363 	case '-':
1364 		opname = "sub";
1365 		break;
1366 	case '&':
1367 		opname = "and";
1368 		break;
1369 	case '|':
1370 		opname = "or";
1371 		break;
1372 	case '^':
1373 		opname = "xor";
1374 		break;
1375 	case SPECIAL_LEFTSHIFT:
1376 		opname = "shl";
1377 		break;
1378 	case SPECIAL_RIGHTSHIFT:
1379 		if (is_signed)
1380 			opname = "sar";
1381 		else
1382 			opname = "shr";
1383 		break;
1384 	case '*':
1385 		if (is_signed)
1386 			opname = "imul";
1387 		else
1388 			opname = "mul";
1389 		break;
1390 	case SPECIAL_LOGICAL_AND:
1391 		warning(expr->pos, "bogus bitwise and for logical op (should use '2*setne + and' or something)");
1392 		opname = "and";
1393 		break;
1394 	case SPECIAL_LOGICAL_OR:
1395 		warning(expr->pos, "bogus bitwise or for logical op (should use 'or + setne' or something)");
1396 		opname = "or";
1397 		break;
1398 	default:
1399 		error_die(expr->pos, "unhandled binop '%s'\n", show_special(expr->op));
1400 		break;
1401 	}
1402 
1403 	dest = get_reg_value(right, &regclass_32);
1404 	src = get_reg_value(left, &regclass_32);
1405 	switch (expr->ctype->bit_size) {
1406 	case 8:
1407 		suffix = "b";
1408 		break;
1409 	case 16:
1410 		suffix = "w";
1411 		break;
1412 	case 32:
1413 		suffix = "l";
1414 		break;
1415 	case 64:
1416 		suffix = "q";		/* FIXME */
1417 		break;
1418 	default:
1419 		assert(0);
1420 		break;
1421 	}
1422 
1423 	snprintf(opstr, sizeof(opstr), "%s%s", opname, suffix);
1424 
1425 	/* perform binop */
1426 	insn(opstr, src, dest, NULL);
1427 	put_reg(src);
1428 
1429 	/* store result in new pseudo / stack slot */
1430 	new = stack_alloc(expr->ctype->bit_size / 8);
1431 	emit_move(dest, new, NULL, "end EXPR_BINOP");
1432 
1433 	put_reg(dest);
1434 
1435 	return new;
1436 }
1437 
emit_conditional_test(struct storage * val)1438 static int emit_conditional_test(struct storage *val)
1439 {
1440 	struct storage *reg;
1441 	struct storage *target_val;
1442 	int target_false;
1443 
1444 	/* load result into EAX */
1445 	emit_comment("begin if/conditional");
1446 	reg = get_reg_value(val, &regclass_32);
1447 
1448 	/* compare result with zero */
1449 	insn("test", reg, reg, NULL);
1450 	put_reg(reg);
1451 
1452 	/* create conditional-failed label to jump to */
1453 	target_false = new_label();
1454 	target_val = new_storage(STOR_LABEL);
1455 	target_val->label = target_false;
1456 	target_val->flags = STOR_WANTS_FREE;
1457 	insn("jz", target_val, NULL, NULL);
1458 
1459 	return target_false;
1460 }
1461 
emit_conditional_end(int target_false)1462 static int emit_conditional_end(int target_false)
1463 {
1464 	struct storage *cond_end_st;
1465 	int cond_end;
1466 
1467 	/* finished generating code for if-true statement.
1468 	 * add a jump-to-end jump to avoid falling through
1469 	 * to the if-false statement code.
1470 	 */
1471 	cond_end = new_label();
1472 	cond_end_st = new_storage(STOR_LABEL);
1473 	cond_end_st->label = cond_end;
1474 	cond_end_st->flags = STOR_WANTS_FREE;
1475 	insn("jmp", cond_end_st, NULL, NULL);
1476 
1477 	/* if we have both if-true and if-false statements,
1478 	 * the failed-conditional case will fall through to here
1479 	 */
1480 	emit_label(target_false, NULL);
1481 
1482 	return cond_end;
1483 }
1484 
emit_if_conditional(struct statement * stmt)1485 static void emit_if_conditional(struct statement *stmt)
1486 {
1487 	struct storage *val;
1488 	int cond_end;
1489 
1490 	/* emit test portion of conditional */
1491 	val = x86_expression(stmt->if_conditional);
1492 	cond_end = emit_conditional_test(val);
1493 
1494 	/* emit if-true statement */
1495 	x86_statement(stmt->if_true);
1496 
1497 	/* emit if-false statement, if present */
1498 	if (stmt->if_false) {
1499 		cond_end = emit_conditional_end(cond_end);
1500 		x86_statement(stmt->if_false);
1501 	}
1502 
1503 	/* end of conditional; jump target for if-true branch */
1504 	emit_label(cond_end, "end if");
1505 }
1506 
emit_inc_dec(struct expression * expr,int postop)1507 static struct storage *emit_inc_dec(struct expression *expr, int postop)
1508 {
1509 	struct storage *addr = x86_address_gen(expr->unop);
1510 	struct storage *retval;
1511 	char opname[16];
1512 
1513 	strcpy(opname, opbits(expr->op == SPECIAL_INCREMENT ? "inc" : "dec",
1514 			      expr->ctype->bit_size));
1515 
1516 	if (postop) {
1517 		struct storage *new = stack_alloc(4);
1518 
1519 		emit_copy(new, addr, expr->unop->ctype);
1520 
1521 		retval = new;
1522 	} else
1523 		retval = addr;
1524 
1525 	insn(opname, addr, NULL, NULL);
1526 
1527 	return retval;
1528 }
1529 
emit_postop(struct expression * expr)1530 static struct storage *emit_postop(struct expression *expr)
1531 {
1532 	return emit_inc_dec(expr, 1);
1533 }
1534 
emit_return_stmt(struct statement * stmt)1535 static struct storage *emit_return_stmt(struct statement *stmt)
1536 {
1537 	struct function *f = current_func;
1538 	struct expression *expr = stmt->ret_value;
1539 	struct storage *val = NULL, *jmplbl;
1540 
1541 	if (expr && expr->ctype) {
1542 		val = x86_expression(expr);
1543 		assert(val != NULL);
1544 		emit_move(val, REG_EAX, expr->ctype, "return");
1545 	}
1546 
1547 	jmplbl = new_storage(STOR_LABEL);
1548 	jmplbl->flags |= STOR_WANTS_FREE;
1549 	jmplbl->label = f->ret_target;
1550 	insn("jmp", jmplbl, NULL, NULL);
1551 
1552 	return val;
1553 }
1554 
emit_conditional_expr(struct expression * expr)1555 static struct storage *emit_conditional_expr(struct expression *expr)
1556 {
1557 	struct storage *cond, *stot = NULL, *stof = NULL;
1558 	struct storage *new = stack_alloc(expr->ctype->bit_size / 8);
1559 	int target_false, cond_end;
1560 
1561 	/* evaluate conditional */
1562 	cond = x86_expression(expr->conditional);
1563 	target_false = emit_conditional_test(cond);
1564 
1565 	/* handle if-true part of the expression */
1566 	stot = x86_expression(expr->cond_true);
1567 
1568 	emit_copy(new, stot, expr->ctype);
1569 
1570 	cond_end = emit_conditional_end(target_false);
1571 
1572 	/* handle if-false part of the expression */
1573 	stof = x86_expression(expr->cond_false);
1574 
1575 	emit_copy(new, stof, expr->ctype);
1576 
1577 	/* end of conditional; jump target for if-true branch */
1578 	emit_label(cond_end, "end conditional");
1579 
1580 	return new;
1581 }
1582 
emit_select_expr(struct expression * expr)1583 static struct storage *emit_select_expr(struct expression *expr)
1584 {
1585 	struct storage *cond = x86_expression(expr->conditional);
1586 	struct storage *stot = x86_expression(expr->cond_true);
1587 	struct storage *stof = x86_expression(expr->cond_false);
1588 	struct storage *reg_cond, *reg_true, *reg_false;
1589 	struct storage *new = stack_alloc(4);
1590 
1591 	emit_comment("begin SELECT");
1592 	reg_cond = get_reg_value(cond, get_regclass(expr->conditional));
1593 	reg_true = get_reg_value(stot, get_regclass(expr));
1594 	reg_false = get_reg_value(stof, get_regclass(expr));
1595 
1596 	/*
1597 	 * Do the actual select: check the conditional for zero,
1598 	 * move false over true if zero
1599 	 */
1600 	insn("test", reg_cond, reg_cond, NULL);
1601 	insn("cmovz", reg_false, reg_true, NULL);
1602 
1603 	/* Store it back */
1604 	emit_move(reg_true, new, expr->ctype, NULL);
1605 	put_reg(reg_cond);
1606 	put_reg(reg_true);
1607 	put_reg(reg_false);
1608 	emit_comment("end SELECT");
1609 	return new;
1610 }
1611 
emit_symbol_expr_init(struct symbol * sym)1612 static struct storage *emit_symbol_expr_init(struct symbol *sym)
1613 {
1614 	struct expression *expr = sym->initializer;
1615 	struct symbol_private *priv = sym->aux;
1616 
1617 	if (priv == NULL) {
1618 		priv = calloc(1, sizeof(*priv));
1619 		sym->aux = priv;
1620 
1621 		if (expr == NULL) {
1622 			struct storage *new = stack_alloc(4);
1623 			fprintf(stderr, "FIXME! no value for symbol %s.  creating pseudo %d (stack offset %d)\n",
1624 				show_ident(sym->ident),
1625 				new->pseudo, new->pseudo * 4);
1626 			priv->addr = new;
1627 		} else {
1628 			priv->addr = x86_expression(expr);
1629 		}
1630 	}
1631 
1632 	return priv->addr;
1633 }
1634 
emit_string_expr(struct expression * expr)1635 static struct storage *emit_string_expr(struct expression *expr)
1636 {
1637 	struct function *f = current_func;
1638 	int label = new_label();
1639 	struct storage *new;
1640 
1641 	push_cstring(f, expr->string, label);
1642 
1643 	new = new_storage(STOR_LABEL);
1644 	new->label = label;
1645 	new->flags = STOR_LABEL_VAL | STOR_WANTS_FREE;
1646 	return new;
1647 }
1648 
emit_cast_expr(struct expression * expr)1649 static struct storage *emit_cast_expr(struct expression *expr)
1650 {
1651 	struct symbol *old_type, *new_type;
1652 	struct storage *op = x86_expression(expr->cast_expression);
1653 	int oldbits, newbits;
1654 	struct storage *new;
1655 
1656 	old_type = expr->cast_expression->ctype;
1657 	new_type = expr->cast_type;
1658 
1659 	oldbits = old_type->bit_size;
1660 	newbits = new_type->bit_size;
1661 	if (oldbits >= newbits)
1662 		return op;
1663 
1664 	emit_move(op, REG_EAX, old_type, "begin cast ..");
1665 
1666 	new = stack_alloc(newbits / 8);
1667 	emit_move(REG_EAX, new, new_type, ".... end cast");
1668 
1669 	return new;
1670 }
1671 
emit_regular_preop(struct expression * expr)1672 static struct storage *emit_regular_preop(struct expression *expr)
1673 {
1674 	struct storage *target = x86_expression(expr->unop);
1675 	struct storage *val, *new = stack_alloc(4);
1676 	const char *opname = NULL;
1677 
1678 	switch (expr->op) {
1679 	case '!':
1680 		val = new_storage(STOR_VALUE);
1681 		val->flags = STOR_WANTS_FREE;
1682 		emit_move(val, REG_EDX, NULL, NULL);
1683 		emit_move(target, REG_EAX, expr->unop->ctype, NULL);
1684 		insn("test", REG_EAX, REG_EAX, NULL);
1685 		insn("setz", REG_DL, NULL, NULL);
1686 		emit_move(REG_EDX, new, expr->unop->ctype, NULL);
1687 
1688 		break;
1689 	case '~':
1690 		opname = "not";
1691 	case '-':
1692 		if (!opname)
1693 			opname = "neg";
1694 		emit_move(target, REG_EAX, expr->unop->ctype, NULL);
1695 		insn(opname, REG_EAX, NULL, NULL);
1696 		emit_move(REG_EAX, new, expr->unop->ctype, NULL);
1697 		break;
1698 	default:
1699 		assert(0);
1700 		break;
1701 	}
1702 
1703 	return new;
1704 }
1705 
emit_case_statement(struct statement * stmt)1706 static void emit_case_statement(struct statement *stmt)
1707 {
1708 	emit_labelsym(stmt->case_label, NULL);
1709 	x86_statement(stmt->case_statement);
1710 }
1711 
emit_switch_statement(struct statement * stmt)1712 static void emit_switch_statement(struct statement *stmt)
1713 {
1714 	struct storage *val = x86_expression(stmt->switch_expression);
1715 	struct symbol *sym, *default_sym = NULL;
1716 	struct storage *labelsym, *label;
1717 	int switch_end = 0;
1718 
1719 	emit_move(val, REG_EAX, stmt->switch_expression->ctype, "begin case");
1720 
1721 	/*
1722 	 * This is where a _real_ back-end would go through the
1723 	 * cases to decide whether to use a lookup table or a
1724 	 * series of comparisons etc
1725 	 */
1726 	FOR_EACH_PTR(stmt->switch_case->symbol_list, sym) {
1727 		struct statement *case_stmt = sym->stmt;
1728 		struct expression *expr = case_stmt->case_expression;
1729 		struct expression *to = case_stmt->case_to;
1730 
1731 		/* default: */
1732 		if (!expr)
1733 			default_sym = sym;
1734 
1735 		/* case NNN: */
1736 		else {
1737 			struct storage *case_val = new_val(expr->value);
1738 
1739 			assert (expr->type == EXPR_VALUE);
1740 
1741 			insn("cmpl", case_val, REG_EAX, NULL);
1742 
1743 			if (!to) {
1744 				labelsym = new_labelsym(sym);
1745 				insn("je", labelsym, NULL, NULL);
1746 			} else {
1747 				int next_test;
1748 
1749 				label = new_storage(STOR_LABEL);
1750 				label->flags |= STOR_WANTS_FREE;
1751 				label->label = next_test = new_label();
1752 
1753 				/* FIXME: signed/unsigned */
1754 				insn("jl", label, NULL, NULL);
1755 
1756 				case_val = new_val(to->value);
1757 				insn("cmpl", case_val, REG_EAX, NULL);
1758 
1759 				/* TODO: implement and use refcounting... */
1760 				label = new_storage(STOR_LABEL);
1761 				label->flags |= STOR_WANTS_FREE;
1762 				label->label = next_test;
1763 
1764 				/* FIXME: signed/unsigned */
1765 				insn("jg", label, NULL, NULL);
1766 
1767 				labelsym = new_labelsym(sym);
1768 				insn("jmp", labelsym, NULL, NULL);
1769 
1770 				emit_label(next_test, NULL);
1771 			}
1772 		}
1773 	} END_FOR_EACH_PTR(sym);
1774 
1775 	if (default_sym) {
1776 		labelsym = new_labelsym(default_sym);
1777 		insn("jmp", labelsym, NULL, "default");
1778 	} else {
1779 		label = new_storage(STOR_LABEL);
1780 		label->flags |= STOR_WANTS_FREE;
1781 		label->label = switch_end = new_label();
1782 		insn("jmp", label, NULL, "goto end of switch");
1783 	}
1784 
1785 	x86_statement(stmt->switch_statement);
1786 
1787 	if (stmt->switch_break->used)
1788 		emit_labelsym(stmt->switch_break, NULL);
1789 
1790 	if (switch_end)
1791 		emit_label(switch_end, NULL);
1792 }
1793 
x86_struct_member(struct symbol * sym)1794 static void x86_struct_member(struct symbol *sym)
1795 {
1796 	printf("\t%s:%d:%ld at offset %ld.%d", show_ident(sym->ident), sym->bit_size, sym->ctype.alignment, sym->offset, sym->bit_offset);
1797 	printf("\n");
1798 }
1799 
x86_symbol(struct symbol * sym)1800 static void x86_symbol(struct symbol *sym)
1801 {
1802 	struct symbol *type;
1803 
1804 	if (!sym)
1805 		return;
1806 
1807 	type = sym->ctype.base_type;
1808 	if (!type)
1809 		return;
1810 
1811 	/*
1812 	 * Show actual implementation information
1813 	 */
1814 	switch (type->type) {
1815 
1816 	case SYM_ARRAY:
1817 		if (sym->initializer)
1818 			emit_array(sym);
1819 		else
1820 			emit_array_noinit(sym);
1821 		break;
1822 
1823 	case SYM_BASETYPE:
1824 		if (sym->initializer) {
1825 			emit_object_pre(show_ident(sym->ident),
1826 					sym->ctype.modifiers,
1827 				        sym->ctype.alignment,
1828 					sym->bit_size / 8);
1829 			emit_scalar(sym->initializer, sym->bit_size);
1830 			stor_sym_init(sym);
1831 		} else
1832 			emit_scalar_noinit(sym);
1833 		break;
1834 
1835 	case SYM_STRUCT:
1836 	case SYM_UNION: {
1837 		struct symbol *member;
1838 
1839 		printf(" {\n");
1840 		FOR_EACH_PTR(type->symbol_list, member) {
1841 			x86_struct_member(member);
1842 		} END_FOR_EACH_PTR(member);
1843 		printf("}\n");
1844 		break;
1845 	}
1846 
1847 	case SYM_FN: {
1848 		struct statement *stmt = type->stmt;
1849 		if (stmt) {
1850 			emit_func_pre(sym);
1851 			x86_statement(stmt);
1852 			emit_func_post(sym);
1853 		}
1854 		break;
1855 	}
1856 
1857 	default:
1858 		break;
1859 	}
1860 
1861 	if (sym->initializer && (type->type != SYM_BASETYPE) &&
1862 	    (type->type != SYM_ARRAY)) {
1863 		printf(" = \n");
1864 		x86_expression(sym->initializer);
1865 	}
1866 }
1867 
1868 static void x86_symbol_init(struct symbol *sym);
1869 
x86_symbol_decl(struct symbol_list * syms)1870 static void x86_symbol_decl(struct symbol_list *syms)
1871 {
1872 	struct symbol *sym;
1873 	FOR_EACH_PTR(syms, sym) {
1874 		x86_symbol_init(sym);
1875 	} END_FOR_EACH_PTR(sym);
1876 }
1877 
loopstk_push(int cont_lbl,int loop_bottom_lbl)1878 static void loopstk_push(int cont_lbl, int loop_bottom_lbl)
1879 {
1880 	struct function *f = current_func;
1881 	struct loop_stack *ls;
1882 
1883 	ls = malloc(sizeof(*ls));
1884 	ls->continue_lbl = cont_lbl;
1885 	ls->loop_bottom_lbl = loop_bottom_lbl;
1886 	ls->next = f->loop_stack;
1887 	f->loop_stack = ls;
1888 }
1889 
loopstk_pop(void)1890 static void loopstk_pop(void)
1891 {
1892 	struct function *f = current_func;
1893 	struct loop_stack *ls;
1894 
1895 	assert(f->loop_stack != NULL);
1896 	ls = f->loop_stack;
1897 	f->loop_stack = f->loop_stack->next;
1898 	free(ls);
1899 }
1900 
loopstk_break(void)1901 static int loopstk_break(void)
1902 {
1903 	return current_func->loop_stack->loop_bottom_lbl;
1904 }
1905 
loopstk_continue(void)1906 static int loopstk_continue(void)
1907 {
1908 	return current_func->loop_stack->continue_lbl;
1909 }
1910 
emit_loop(struct statement * stmt)1911 static void emit_loop(struct statement *stmt)
1912 {
1913 	struct statement  *pre_statement = stmt->iterator_pre_statement;
1914 	struct expression *pre_condition = stmt->iterator_pre_condition;
1915 	struct statement  *statement = stmt->iterator_statement;
1916 	struct statement  *post_statement = stmt->iterator_post_statement;
1917 	struct expression *post_condition = stmt->iterator_post_condition;
1918 	int loop_top = 0, loop_bottom, loop_continue;
1919 	int have_bottom = 0;
1920 	struct storage *val;
1921 
1922 	loop_bottom = new_label();
1923 	loop_continue = new_label();
1924 	loopstk_push(loop_continue, loop_bottom);
1925 
1926 	x86_symbol_decl(stmt->iterator_syms);
1927 	x86_statement(pre_statement);
1928 	if (!post_condition || post_condition->type != EXPR_VALUE || post_condition->value) {
1929 		loop_top = new_label();
1930 		emit_label(loop_top, "loop top");
1931 	}
1932 	if (pre_condition) {
1933 		if (pre_condition->type == EXPR_VALUE) {
1934 			if (!pre_condition->value) {
1935 				struct storage *lbv;
1936 				lbv = new_storage(STOR_LABEL);
1937 				lbv->label = loop_bottom;
1938 				lbv->flags = STOR_WANTS_FREE;
1939 				insn("jmp", lbv, NULL, "go to loop bottom");
1940 				have_bottom = 1;
1941 			}
1942 		} else {
1943 			struct storage *lbv = new_storage(STOR_LABEL);
1944 			lbv->label = loop_bottom;
1945 			lbv->flags = STOR_WANTS_FREE;
1946 			have_bottom = 1;
1947 
1948 			val = x86_expression(pre_condition);
1949 
1950 			emit_move(val, REG_EAX, NULL, "loop pre condition");
1951 			insn("test", REG_EAX, REG_EAX, NULL);
1952 			insn("jz", lbv, NULL, NULL);
1953 		}
1954 	}
1955 	x86_statement(statement);
1956 	if (stmt->iterator_continue->used)
1957 		emit_label(loop_continue, "'continue' iterator");
1958 	x86_statement(post_statement);
1959 	if (!post_condition) {
1960 		struct storage *lbv = new_storage(STOR_LABEL);
1961 		lbv->label = loop_top;
1962 		lbv->flags = STOR_WANTS_FREE;
1963 		insn("jmp", lbv, NULL, "go to loop top");
1964 	} else if (post_condition->type == EXPR_VALUE) {
1965 		if (post_condition->value) {
1966 			struct storage *lbv = new_storage(STOR_LABEL);
1967 			lbv->label = loop_top;
1968 			lbv->flags = STOR_WANTS_FREE;
1969 			insn("jmp", lbv, NULL, "go to loop top");
1970 		}
1971 	} else {
1972 		struct storage *lbv = new_storage(STOR_LABEL);
1973 		lbv->label = loop_top;
1974 		lbv->flags = STOR_WANTS_FREE;
1975 
1976 		val = x86_expression(post_condition);
1977 
1978 		emit_move(val, REG_EAX, NULL, "loop post condition");
1979 		insn("test", REG_EAX, REG_EAX, NULL);
1980 		insn("jnz", lbv, NULL, NULL);
1981 	}
1982 	if (have_bottom || stmt->iterator_break->used)
1983 		emit_label(loop_bottom, "loop bottom");
1984 
1985 	loopstk_pop();
1986 }
1987 
1988 /*
1989  * Print out a statement
1990  */
x86_statement(struct statement * stmt)1991 static struct storage *x86_statement(struct statement *stmt)
1992 {
1993 	if (!stmt)
1994 		return NULL;
1995 	switch (stmt->type) {
1996 	default:
1997 		return NULL;
1998 	case STMT_RETURN:
1999 		return emit_return_stmt(stmt);
2000 	case STMT_DECLARATION:
2001 		x86_symbol_decl(stmt->declaration);
2002 		break;
2003 	case STMT_COMPOUND: {
2004 		struct statement *s;
2005 		struct storage *last = NULL;
2006 
2007 		FOR_EACH_PTR(stmt->stmts, s) {
2008 			last = x86_statement(s);
2009 		} END_FOR_EACH_PTR(s);
2010 
2011 		return last;
2012 	}
2013 
2014 	case STMT_EXPRESSION:
2015 		return x86_expression(stmt->expression);
2016 	case STMT_IF:
2017 		emit_if_conditional(stmt);
2018 		return NULL;
2019 
2020 	case STMT_CASE:
2021 		emit_case_statement(stmt);
2022 		break;
2023 	case STMT_SWITCH:
2024 		emit_switch_statement(stmt);
2025 		break;
2026 
2027 	case STMT_ITERATOR:
2028 		emit_loop(stmt);
2029 		break;
2030 
2031 	case STMT_NONE:
2032 		break;
2033 
2034 	case STMT_LABEL:
2035 		printf(".L%p:\n", stmt->label_identifier);
2036 		x86_statement(stmt->label_statement);
2037 		break;
2038 
2039 	case STMT_GOTO:
2040 		if (stmt->goto_expression) {
2041 			struct storage *val = x86_expression(stmt->goto_expression);
2042 			printf("\tgoto *v%d\n", val->pseudo);
2043 		} else if (!strcmp("break", show_ident(stmt->goto_label->ident))) {
2044 			struct storage *lbv = new_storage(STOR_LABEL);
2045 			lbv->label = loopstk_break();
2046 			lbv->flags = STOR_WANTS_FREE;
2047 			insn("jmp", lbv, NULL, "'break'; go to loop bottom");
2048 		} else if (!strcmp("continue", show_ident(stmt->goto_label->ident))) {
2049 			struct storage *lbv = new_storage(STOR_LABEL);
2050 			lbv->label = loopstk_continue();
2051 			lbv->flags = STOR_WANTS_FREE;
2052 			insn("jmp", lbv, NULL, "'continue'; go to loop top");
2053 		} else {
2054 			struct storage *labelsym = new_labelsym(stmt->goto_label);
2055 			insn("jmp", labelsym, NULL, NULL);
2056 		}
2057 		break;
2058 	case STMT_ASM:
2059 		printf("\tasm( .... )\n");
2060 		break;
2061 	}
2062 	return NULL;
2063 }
2064 
x86_call_expression(struct expression * expr)2065 static struct storage *x86_call_expression(struct expression *expr)
2066 {
2067 	struct function *f = current_func;
2068 	struct symbol *direct;
2069 	struct expression *arg, *fn;
2070 	struct storage *retval, *fncall;
2071 	int framesize;
2072 	char s[64];
2073 
2074 	if (!expr->ctype) {
2075 		warning(expr->pos, "\tcall with no type!");
2076 		return NULL;
2077 	}
2078 
2079 	framesize = 0;
2080 	FOR_EACH_PTR_REVERSE(expr->args, arg) {
2081 		struct storage *new = x86_expression(arg);
2082 		int size = arg->ctype->bit_size;
2083 
2084 		/*
2085 		 * FIXME: i386 SysV ABI dictates that values
2086 		 * smaller than 32 bits should be placed onto
2087 		 * the stack as 32-bit objects.  We should not
2088 		 * blindly do a 32-bit push on objects smaller
2089 		 * than 32 bits.
2090 		 */
2091 		if (size < 32)
2092 			size = 32;
2093 		insn("pushl", new, NULL,
2094 		     !framesize ? "begin function call" : NULL);
2095 
2096 		framesize += bits_to_bytes(size);
2097 	} END_FOR_EACH_PTR_REVERSE(arg);
2098 
2099 	fn = expr->fn;
2100 
2101 	/* Remove dereference, if any */
2102 	direct = NULL;
2103 	if (fn->type == EXPR_PREOP) {
2104 		if (fn->unop->type == EXPR_SYMBOL) {
2105 			struct symbol *sym = fn->unop->symbol;
2106 			if (sym->ctype.base_type->type == SYM_FN)
2107 				direct = sym;
2108 		}
2109 	}
2110 	if (direct) {
2111 		struct storage *direct_stor = new_storage(STOR_SYM);
2112 		direct_stor->flags |= STOR_WANTS_FREE;
2113 		direct_stor->sym = direct;
2114 		insn("call", direct_stor, NULL, NULL);
2115 	} else {
2116 		fncall = x86_expression(fn);
2117 		emit_move(fncall, REG_EAX, fn->ctype, NULL);
2118 
2119 		strcpy(s, "\tcall\t*%eax\n");
2120 		push_text_atom(f, s);
2121 	}
2122 
2123 	/* FIXME: pay attention to BITS_IN_POINTER */
2124 	if (framesize) {
2125 		struct storage *val = new_storage(STOR_VALUE);
2126 		val->value = (long long) framesize;
2127 		val->flags = STOR_WANTS_FREE;
2128 		insn("addl", val, REG_ESP, NULL);
2129 	}
2130 
2131 	retval = stack_alloc(4);
2132 	emit_move(REG_EAX, retval, NULL, "end function call");
2133 
2134 	return retval;
2135 }
2136 
x86_address_gen(struct expression * expr)2137 static struct storage *x86_address_gen(struct expression *expr)
2138 {
2139 	struct function *f = current_func;
2140 	struct storage *addr;
2141 	struct storage *new;
2142 	char s[32];
2143 
2144 	addr = x86_expression(expr->unop);
2145 	if (expr->unop->type == EXPR_SYMBOL)
2146 		return addr;
2147 
2148 	emit_move(addr, REG_EAX, NULL, "begin deref ..");
2149 
2150 	/* FIXME: operand size */
2151 	strcpy(s, "\tmovl\t(%eax), %ecx\n");
2152 	push_text_atom(f, s);
2153 
2154 	new = stack_alloc(4);
2155 	emit_move(REG_ECX, new, NULL, ".... end deref");
2156 
2157 	return new;
2158 }
2159 
x86_assignment(struct expression * expr)2160 static struct storage *x86_assignment(struct expression *expr)
2161 {
2162 	struct expression *target = expr->left;
2163 	struct storage *val, *addr;
2164 
2165 	if (!expr->ctype)
2166 		return NULL;
2167 
2168 	val = x86_expression(expr->right);
2169 	addr = x86_address_gen(target);
2170 
2171 	switch (val->type) {
2172 	/* copy, where both operands are memory */
2173 	case STOR_PSEUDO:
2174 	case STOR_ARG:
2175 		emit_copy(addr, val, expr->ctype);
2176 		break;
2177 
2178 	/* copy, one or zero operands are memory */
2179 	case STOR_REG:
2180 	case STOR_SYM:
2181 	case STOR_VALUE:
2182 	case STOR_LABEL:
2183 		emit_move(val, addr, expr->left->ctype, NULL);
2184 		break;
2185 
2186 	case STOR_LABELSYM:
2187 		assert(0);
2188 		break;
2189 	}
2190 	return val;
2191 }
2192 
x86_initialization(struct symbol * sym,struct expression * expr)2193 static int x86_initialization(struct symbol *sym, struct expression *expr)
2194 {
2195 	struct storage *val, *addr;
2196 	int bits;
2197 
2198 	if (!expr->ctype)
2199 		return 0;
2200 
2201 	bits = expr->ctype->bit_size;
2202 	val = x86_expression(expr);
2203 	addr = x86_symbol_expr(sym);
2204 	// FIXME! The "target" expression is for bitfield store information.
2205 	// Leave it NULL, which works fine.
2206 	emit_store(NULL, addr, val, bits);
2207 	return 0;
2208 }
2209 
x86_access(struct expression * expr)2210 static struct storage *x86_access(struct expression *expr)
2211 {
2212 	return x86_address_gen(expr);
2213 }
2214 
x86_preop(struct expression * expr)2215 static struct storage *x86_preop(struct expression *expr)
2216 {
2217 	/*
2218 	 * '*' is an lvalue access, and is fundamentally different
2219 	 * from an arithmetic operation. Maybe it should have an
2220 	 * expression type of its own..
2221 	 */
2222 	if (expr->op == '*')
2223 		return x86_access(expr);
2224 	if (expr->op == SPECIAL_INCREMENT || expr->op == SPECIAL_DECREMENT)
2225 		return emit_inc_dec(expr, 0);
2226 	return emit_regular_preop(expr);
2227 }
2228 
x86_symbol_expr(struct symbol * sym)2229 static struct storage *x86_symbol_expr(struct symbol *sym)
2230 {
2231 	struct storage *new = stack_alloc(4);
2232 
2233 	if (sym->ctype.modifiers & (MOD_TOPLEVEL | MOD_EXTERN | MOD_STATIC)) {
2234 		printf("\tmovi.%d\t\tv%d,$%s\n", bits_in_pointer, new->pseudo, show_ident(sym->ident));
2235 		return new;
2236 	}
2237 	if (sym->ctype.modifiers & MOD_ADDRESSABLE) {
2238 		printf("\taddi.%d\t\tv%d,vFP,$%lld\n", bits_in_pointer, new->pseudo, 0LL);
2239 		return new;
2240 	}
2241 	printf("\taddi.%d\t\tv%d,vFP,$offsetof(%s:%p)\n", bits_in_pointer, new->pseudo, show_ident(sym->ident), sym);
2242 	return new;
2243 }
2244 
x86_symbol_init(struct symbol * sym)2245 static void x86_symbol_init(struct symbol *sym)
2246 {
2247 	struct symbol_private *priv = sym->aux;
2248 	struct expression *expr = sym->initializer;
2249 	struct storage *new;
2250 
2251 	if (expr)
2252 		new = x86_expression(expr);
2253 	else
2254 		new = stack_alloc(sym->bit_size / 8);
2255 
2256 	if (!priv) {
2257 		priv = calloc(1, sizeof(*priv));
2258 		sym->aux = priv;
2259 		/* FIXME: leak! we don't free... */
2260 		/* (well, we don't free symbols either) */
2261 	}
2262 
2263 	priv->addr = new;
2264 }
2265 
x86_label_expr(struct expression * expr)2266 static struct storage *x86_label_expr(struct expression *expr)
2267 {
2268 	struct storage *new = stack_alloc(4);
2269 	printf("\tmovi.%d\t\tv%d,.L%p\n", bits_in_pointer, new->pseudo, expr->label_symbol);
2270 	return new;
2271 }
2272 
x86_statement_expr(struct expression * expr)2273 static struct storage *x86_statement_expr(struct expression *expr)
2274 {
2275 	return x86_statement(expr->statement);
2276 }
2277 
x86_position_expr(struct expression * expr,struct symbol * base)2278 static int x86_position_expr(struct expression *expr, struct symbol *base)
2279 {
2280 	struct storage *new = x86_expression(expr->init_expr);
2281 	struct symbol *ctype = expr->init_expr->ctype;
2282 
2283 	printf("\tinsert v%d at [%d:%d] of %s\n", new->pseudo,
2284 		expr->init_offset, ctype->bit_offset,
2285 		show_ident(base->ident));
2286 	return 0;
2287 }
2288 
x86_initializer_expr(struct expression * expr,struct symbol * ctype)2289 static void x86_initializer_expr(struct expression *expr, struct symbol *ctype)
2290 {
2291 	struct expression *entry;
2292 
2293 	FOR_EACH_PTR(expr->expr_list, entry) {
2294 		// Nested initializers have their positions already
2295 		// recursively calculated - just output them too
2296 		if (entry->type == EXPR_INITIALIZER) {
2297 			x86_initializer_expr(entry, ctype);
2298 			continue;
2299 		}
2300 
2301 		// Ignore initializer indexes and identifiers - the
2302 		// evaluator has taken them into account
2303 		if (entry->type == EXPR_IDENTIFIER || entry->type == EXPR_INDEX)
2304 			continue;
2305 		if (entry->type == EXPR_POS) {
2306 			x86_position_expr(entry, ctype);
2307 			continue;
2308 		}
2309 		x86_initialization(ctype, entry);
2310 	} END_FOR_EACH_PTR(entry);
2311 }
2312 
2313 /*
2314  * Print out an expression. Return the pseudo that contains the
2315  * variable.
2316  */
x86_expression(struct expression * expr)2317 static struct storage *x86_expression(struct expression *expr)
2318 {
2319 	if (!expr)
2320 		return NULL;
2321 
2322 	if (!expr->ctype) {
2323 		struct position *pos = &expr->pos;
2324 		printf("\tno type at %s:%d:%d\n",
2325 			stream_name(pos->stream),
2326 			pos->line, pos->pos);
2327 		return NULL;
2328 	}
2329 
2330 	switch (expr->type) {
2331 	default:
2332 		return NULL;
2333 	case EXPR_CALL:
2334 		return x86_call_expression(expr);
2335 
2336 	case EXPR_ASSIGNMENT:
2337 		return x86_assignment(expr);
2338 
2339 	case EXPR_COMPARE:
2340 		return emit_compare(expr);
2341 	case EXPR_BINOP:
2342 	case EXPR_COMMA:
2343 	case EXPR_LOGICAL:
2344 		return emit_binop(expr);
2345 	case EXPR_PREOP:
2346 		return x86_preop(expr);
2347 	case EXPR_POSTOP:
2348 		return emit_postop(expr);
2349 	case EXPR_SYMBOL:
2350 		return emit_symbol_expr_init(expr->symbol);
2351 	case EXPR_DEREF:
2352 	case EXPR_SIZEOF:
2353 	case EXPR_ALIGNOF:
2354 		warning(expr->pos, "invalid expression after evaluation");
2355 		return NULL;
2356 	case EXPR_CAST:
2357 	case EXPR_FORCE_CAST:
2358 	case EXPR_IMPLIED_CAST:
2359 		return emit_cast_expr(expr);
2360 	case EXPR_VALUE:
2361 		return emit_value(expr);
2362 	case EXPR_STRING:
2363 		return emit_string_expr(expr);
2364 	case EXPR_INITIALIZER:
2365 		x86_initializer_expr(expr, expr->ctype);
2366 		return NULL;
2367 	case EXPR_SELECT:
2368 		return emit_select_expr(expr);
2369 	case EXPR_CONDITIONAL:
2370 		return emit_conditional_expr(expr);
2371 	case EXPR_STATEMENT:
2372 		return x86_statement_expr(expr);
2373 	case EXPR_LABEL:
2374 		return x86_label_expr(expr);
2375 
2376 	// None of these should exist as direct expressions: they are only
2377 	// valid as sub-expressions of initializers.
2378 	case EXPR_POS:
2379 		warning(expr->pos, "unable to show plain initializer position expression");
2380 		return NULL;
2381 	case EXPR_IDENTIFIER:
2382 		warning(expr->pos, "unable to show identifier expression");
2383 		return NULL;
2384 	case EXPR_INDEX:
2385 		warning(expr->pos, "unable to show index expression");
2386 		return NULL;
2387 	case EXPR_TYPE:
2388 		warning(expr->pos, "unable to show type expression");
2389 		return NULL;
2390 	case EXPR_FVALUE:
2391 		warning(expr->pos, "floating point support is not implemented");
2392 		return NULL;
2393 	}
2394 	return NULL;
2395 }
2396