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