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