gen: fix the conditions for movxx operations
[neatcc.git] / ncc.c
blobcd004d03aa04d84564b49001e783b4ad1f52596e
1 /*
2 * neatcc - A small and simple x86_64 C compiler
4 * Copyright (C) 2010 Ali Gholami Rudi
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License, as published by the
8 * Free Software Foundation.
9 */
10 #include <fcntl.h>
11 #include <unistd.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <sys/stat.h>
15 #include <sys/types.h>
16 #include "gen.h"
17 #include "tok.h"
19 #define MAXLOCALS (1 << 10)
20 #define MAXGLOBALS (1 << 10)
21 #define MAXARGS (1 << 5)
22 #define print(s) write(2, (s), strlen(s));
24 #define TYPE_BT(t) ((t)->ptr ? 8 : (t)->bt)
25 #define TYPE_SZ(t) ((t)->ptr ? 8 : (t)->bt & BT_SZMASK)
27 #define T_ARRAY 0x01
28 #define T_STRUCT 0x02
29 #define T_FUNC 0x04
31 #define F_INIT 0x01
32 #define F_STATIC 0x02
33 #define F_EXTERN 0x04
35 struct type {
36 unsigned bt;
37 unsigned flags;
38 int ptr;
39 int id; /* for structs, functions and arrays */
42 /* type stack */
43 static struct type ts[MAXTMP];
44 static int nts;
46 static void ts_push_bt(unsigned bt)
48 ts[nts].ptr = 0;
49 ts[nts].flags = 0;
50 ts[nts++].bt = bt;
53 static void ts_push(struct type *t)
55 memcpy(&ts[nts++], t, sizeof(*t));
56 if (t->flags & (T_FUNC | T_ARRAY) && !t->ptr)
57 o_addr();
60 static void ts_pop(struct type *type)
62 nts--;
63 if (type)
64 *type = ts[nts];
67 void die(char *msg)
69 print(msg);
70 exit(1);
73 void err(char *msg)
75 char err[1 << 7];
76 int len = cpp_loc(err, tok_addr());
77 strcpy(err + len, msg);
78 die(err);
81 struct name {
82 char name[NAMELEN];
83 struct type type;
84 long addr;
85 int unused; /* unreferenced external symbols */
88 static struct name locals[MAXLOCALS];
89 static int nlocals;
90 static struct name globals[MAXGLOBALS];
91 static int nglobals;
93 static void local_add(struct name *name)
95 if (nlocals >= MAXLOCALS)
96 err("nomem: MAXLOCALS reached!\n");
97 memcpy(&locals[nlocals++], name, sizeof(*name));
100 static int global_find(char *name)
102 int i;
103 for (i = 0; i < nglobals; i++)
104 if (!strcmp(name, globals[i].name))
105 return i;
106 return -1;
109 static void global_add(struct name *name)
111 int found = global_find(name->name);
112 int i = found == -1 ? nglobals++ : found;
113 if (nglobals >= MAXGLOBALS)
114 err("nomem: MAXGLOBALS reached!\n");
115 memcpy(&globals[i], name, sizeof(*name));
118 #define MAXENUMS (1 << 10)
120 static struct enumval {
121 char name[NAMELEN];
122 int n;
123 } enums[MAXENUMS];
124 static int nenums;
126 static void enum_add(char *name, int val)
128 struct enumval *ev = &enums[nenums++];
129 if (nenums >= MAXENUMS)
130 err("nomem: MAXENUMS reached!\n");
131 strcpy(ev->name, name);
132 ev->n = val;
135 static int enum_find(int *val, char *name)
137 int i;
138 for (i = nenums - 1; i >= 0; --i)
139 if (!strcmp(name, enums[i].name)) {
140 *val = enums[i].n;
141 return 0;
143 return 1;
146 #define MAXTYPEDEFS (1 << 10)
148 static struct typdefinfo {
149 char name[NAMELEN];
150 struct type type;
151 } typedefs[MAXTYPEDEFS];
152 static int ntypedefs;
154 static void typedef_add(char *name, struct type *type)
156 struct typdefinfo *ti = &typedefs[ntypedefs++];
157 if (ntypedefs >= MAXTYPEDEFS)
158 err("nomem: MAXTYPEDEFS reached!\n");
159 strcpy(ti->name, name);
160 memcpy(&ti->type, type, sizeof(*type));
163 static int typedef_find(char *name)
165 int i;
166 for (i = ntypedefs - 1; i >= 0; --i)
167 if (!strcmp(name, typedefs[i].name))
168 return i;
169 return -1;
172 #define MAXARRAYS (1 << 10)
174 static struct array {
175 struct type type;
176 int n;
177 } arrays[MAXARRAYS];
178 static int narrays;
180 static int array_add(struct type *type, int n)
182 struct array *a = &arrays[narrays++];
183 if (narrays >= MAXARRAYS)
184 err("nomem: MAXARRAYS reached!\n");
185 memcpy(&a->type, type, sizeof(*type));
186 a->n = n;
187 return a - arrays;
190 static void array2ptr(struct type *t)
192 if (!(t->flags & T_ARRAY) || t->ptr)
193 return;
194 memcpy(t, &arrays[t->id].type, sizeof(*t));
195 t->ptr++;
198 #define MAXSTRUCTS (1 << 10)
199 #define MAXFIELDS (1 << 7)
201 static struct structinfo {
202 char name[NAMELEN];
203 struct name fields[MAXFIELDS];
204 int nfields;
205 int isunion;
206 int size;
207 } structs[MAXSTRUCTS];
208 static int nstructs;
210 static int struct_find(char *name, int isunion)
212 int i;
213 for (i = nstructs - 1; i >= 0; --i)
214 if (*structs[i].name && !strcmp(name, structs[i].name) &&
215 structs[i].isunion == isunion)
216 return i;
217 i = nstructs++;
218 if (nstructs >= MAXSTRUCTS)
219 err("nomem: MAXTYPES reached!\n");
220 memset(&structs[i], 0, sizeof(structs[i]));
221 strcpy(structs[i].name, name);
222 structs[i].isunion = isunion;
223 return i;
226 static struct name *struct_field(int id, char *name)
228 struct structinfo *si = &structs[id];
229 int i;
230 for (i = 0; i < si->nfields; i++)
231 if (!strcmp(name, si->fields[i].name))
232 return &si->fields[i];
233 err("field not found\n");
236 #define MAXBREAK (1 << 7)
238 static long breaks[MAXBREAK];
239 static int nbreaks;
240 static long continues[MAXBREAK];
241 static int ncontinues;
243 static void break_fill(long addr, int till)
245 int i;
246 for (i = till; i < nbreaks; i++)
247 o_filljmp2(breaks[i], addr);
248 nbreaks = till;
251 static void continue_fill(long addr, int till)
253 int i;
254 for (i = till; i < ncontinues; i++)
255 o_filljmp2(continues[i], addr);
256 ncontinues = till;
259 static int type_totsz(struct type *t)
261 if (t->ptr)
262 return 8;
263 if (t->flags & T_ARRAY)
264 return arrays[t->id].n * type_totsz(&arrays[t->id].type);
265 return t->flags & T_STRUCT ? structs[t->id].size : BT_SZ(t->bt);
268 static unsigned type_szde(struct type *t)
270 struct type de = *t;
271 array2ptr(&de);
272 de.ptr--;
273 return type_totsz(&de);
276 static int tok_jmp(int tok)
278 if (tok_see() != tok)
279 return 1;
280 tok_get();
281 return 0;
284 static void tok_expect(int tok)
286 if (tok_get() != tok)
287 err("syntax error\n");
290 static unsigned bt_op(unsigned bt1, unsigned bt2)
292 unsigned s1 = BT_SZ(bt1);
293 unsigned s2 = BT_SZ(bt2);
294 return (bt1 | bt2) & BT_SIGNED | (s1 > s2 ? s1 : s2);
297 static void ts_binop(void (*o_sth)(void))
299 struct type t1, t2;
300 ts_pop(&t1);
301 ts_pop(&t2);
302 o_sth();
303 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
306 static void ts_binop_add(void (*o_sth)(void))
308 struct type t1, t2;
309 ts_pop(&t1);
310 ts_pop(&t2);
311 array2ptr(&t1);
312 array2ptr(&t2);
313 if (!t1.ptr && !t2.ptr) {
314 o_sth();
315 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
316 return;
318 if (t1.ptr && !t2.ptr) {
319 struct type t = t2;
320 t2 = t1;
321 t1 = t;
322 o_tmpswap();
324 if (!t1.ptr && t2.ptr)
325 if (type_szde(&t2) > 1) {
326 o_num(type_szde(&t2), 4);
327 o_mul();
329 o_sth();
330 if (t1.ptr && t2.ptr) {
331 o_num(type_szde(&t1), 4);
332 o_div();
333 ts_push_bt(4 | BT_SIGNED);
334 } else {
335 ts_push(&t2);
339 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
340 #define MIN(a, b) ((a) < (b) ? (a) : (b))
342 static void structdef(void *data, struct name *name, unsigned flags)
344 struct structinfo *si = data;
345 if (si->isunion) {
346 name->addr = 0;
347 if (si->size < type_totsz(&name->type))
348 si->size = type_totsz(&name->type);
349 } else {
350 struct type *t = &name->type;
351 int alignment = MIN(8, type_totsz(t));
352 if (t->flags & T_ARRAY && !t->ptr)
353 alignment = MIN(8, type_totsz(&arrays[t->id].type));
354 si->size = ALIGN(si->size, alignment);
355 name->addr = si->size;
356 si->size += type_totsz(&name->type);
358 memcpy(&si->fields[si->nfields++], name, sizeof(*name));
361 static int readdefs(void (*def)(void *, struct name *, unsigned f), void *data);
363 static int struct_create(char *name, int isunion)
365 int id = struct_find(name, isunion);
366 struct structinfo *si = &structs[id];
367 tok_expect('{');
368 while (tok_jmp('}')) {
369 readdefs(structdef, si);
370 tok_expect(';');
372 return id;
375 static void readexpr(void);
377 static void enum_create(void)
379 long n = 0;
380 tok_expect('{');
381 while (tok_jmp('}')) {
382 char name[NAMELEN];
383 tok_expect(TOK_NAME);
384 strcpy(name, tok_id());
385 if (tok_see() == '=') {
386 tok_get();
387 readexpr();
388 ts_pop(NULL);
389 if (o_popnum(&n))
390 err("const expr expected!\n");
392 enum_add(name, n++);
393 tok_jmp(',');
397 static int basetype(struct type *type, unsigned *flags)
399 int sign = 1;
400 int size = 4;
401 int done = 0;
402 int i = 0;
403 int isunion;
404 char name[NAMELEN] = "";
405 *flags = 0;
406 type->flags = 0;
407 type->ptr = 0;
408 while (!done) {
409 switch (tok_see()) {
410 case TOK_STATIC:
411 *flags |= F_STATIC;
412 break;
413 case TOK_EXTERN:
414 *flags |= F_EXTERN;
415 break;
416 case TOK_VOID:
417 sign = 0;
418 size = 0;
419 done = 1;
420 break;
421 case TOK_INT:
422 done = 1;
423 break;
424 case TOK_CHAR:
425 size = 1;
426 done = 1;
427 break;
428 case TOK_SHORT:
429 size = 2;
430 break;
431 case TOK_LONG:
432 size = 8;
433 break;
434 case TOK_SIGNED:
435 break;
436 case TOK_UNSIGNED:
437 sign = 0;
438 break;
439 case TOK_UNION:
440 case TOK_STRUCT:
441 isunion = tok_get() == TOK_UNION;
442 if (!tok_jmp(TOK_NAME))
443 strcpy(name, tok_id());
444 if (tok_see() == '{')
445 type->id = struct_create(name, isunion);
446 else
447 type->id = struct_find(name, isunion);
448 type->flags |= T_STRUCT;
449 type->bt = 8;
450 return 0;
451 case TOK_ENUM:
452 tok_get();
453 tok_jmp(TOK_NAME);
454 if (tok_see() == '{')
455 enum_create();
456 type->bt = 4 | BT_SIGNED;
457 return 0;
458 default:
459 if (tok_see() == TOK_NAME) {
460 int id = typedef_find(tok_id());
461 if (id != -1) {
462 tok_get();
463 memcpy(type, &typedefs[id].type,
464 sizeof(*type));
465 return 0;
468 if (!i)
469 return 1;
470 done = 1;
471 continue;
473 i++;
474 tok_get();
476 type->bt = size | (sign ? BT_SIGNED : 0);
477 return 0;
480 static int readname(struct type *main, char *name,
481 struct type *base, unsigned flags);
483 static int readtype(struct type *type)
485 return readname(type, NULL, NULL, 0);
488 static void readptrs(struct type *type)
490 while (!tok_jmp('*')) {
491 type->ptr++;
492 if (!type->bt)
493 type->bt = 1;
497 /* used to differenciate labels from case and cond exprs */
498 static int ncexpr;
499 static int caseexpr;
501 static void readpre(void);
503 static void readprimary(void)
505 int i;
506 if (!tok_jmp(TOK_NUM)) {
507 long n;
508 int bt = tok_num(&n);
509 ts_push_bt(bt);
510 o_num(n, bt);
511 return;
513 if (!tok_jmp(TOK_STR)) {
514 struct type t;
515 char buf[BUFSIZE];
516 int len;
517 t.bt = 1 | BT_SIGNED;
518 t.ptr = 1;
519 t.flags = 0;
520 ts_push(&t);
521 len = tok_str(buf);
522 o_symaddr(out_mkdat(NULL, buf, len, 0), TYPE_BT(&t));
523 o_addr();
524 return;
526 if (!tok_jmp(TOK_NAME)) {
527 struct name unkn = {0};
528 char *name = unkn.name;
529 int n;
530 strcpy(name, tok_id());
531 /* don't search for labels here */
532 if (!ncexpr && !caseexpr && tok_see() == ':')
533 return;
534 for (i = nlocals - 1; i >= 0; --i) {
535 struct type *t = &locals[i].type;
536 if (!strcmp(locals[i].name, name)) {
537 o_local(locals[i].addr, TYPE_BT(t));
538 ts_push(t);
539 return;
542 if ((n = global_find(name)) != -1) {
543 struct name *g = &globals[n];
544 struct type *t = &g->type;
545 if (g->unused) {
546 g->unused = 0;
547 if (t->flags & T_FUNC && !t->ptr)
548 g->addr = out_mkundef(name, 0);
549 else
550 g->addr = out_mkundef(name, type_totsz(t));
552 o_symaddr(g->addr, TYPE_BT(t));
553 ts_push(t);
554 return;
556 if (!enum_find(&n, name)) {
557 ts_push_bt(4 | BT_SIGNED);
558 o_num(n, 4 | BT_SIGNED);
559 return;
561 if (tok_see() != '(')
562 err("unknown symbol\n");
563 unkn.addr = out_mkundef(unkn.name, 0);
564 global_add(&unkn);
565 ts_push_bt(8);
566 o_symaddr(unkn.addr, 8);
567 return;
569 if (!tok_jmp('(')) {
570 struct type t;
571 if (!readtype(&t)) {
572 struct type o;
573 tok_expect(')');
574 readpre();
575 ts_pop(&o);
576 ts_push(&t);
577 if (!t.ptr || !o.ptr)
578 o_cast(TYPE_BT(&t));
579 } else {
580 readexpr();
581 tok_expect(')');
583 return;
587 void arrayderef(struct type *t)
589 int sz = type_totsz(t);
590 if (sz > 1) {
591 o_num(sz, 4);
592 o_mul();
594 o_add();
595 o_deref(TYPE_BT(t));
598 static void inc_post(void (*op)(void))
600 unsigned bt = TYPE_BT(&ts[nts - 1]);
601 o_tmpcopy();
602 o_load();
603 o_tmpswap();
604 o_tmpcopy();
605 o_num(1, 4);
606 ts_push_bt(bt);
607 ts_push_bt(bt);
608 ts_binop_add(op);
609 ts_pop(NULL);
610 o_assign(bt);
611 o_tmpdrop(1);
614 static void readfield(void)
616 struct name *field;
617 struct type t;
618 tok_expect(TOK_NAME);
619 ts_pop(&t);
620 array2ptr(&t);
621 field = struct_field(t.id, tok_id());
622 if (field->addr) {
623 o_num(field->addr, 4);
624 o_add();
626 o_deref(TYPE_BT(&field->type));
627 ts_push(&field->type);
630 #define MAXFUNCS (1 << 10)
632 static struct funcinfo {
633 struct type args[MAXFIELDS];
634 struct type ret;
635 int nargs;
636 } funcs[MAXFUNCS];
637 static int nfuncs;
638 static unsigned ret_bt;
640 static int func_create(struct type *ret, struct name *args, int nargs)
642 struct funcinfo *fi = &funcs[nfuncs++];
643 int i;
644 if (nfuncs >= MAXFUNCS)
645 err("nomem: MAXFUNCS reached!\n");
646 memcpy(&fi->ret, ret, sizeof(*ret));
647 for (i = 0; i < nargs; i++)
648 memcpy(&fi->args[i], &args[i].type, sizeof(*ret));
649 fi->nargs = nargs;
650 return fi - funcs;
653 static void readcall(void)
655 struct type t;
656 unsigned bt[MAXARGS];
657 struct funcinfo *fi;
658 int argc = 0;
659 int i;
660 ts_pop(&t);
661 if (t.flags & T_FUNC && t.ptr > 0)
662 o_deref(8);
663 fi = t.flags & T_FUNC ? &funcs[t.id] : NULL;
664 if (tok_see() != ')') {
665 readexpr();
666 ts_pop(&t);
667 bt[argc++] = TYPE_BT(&t);
669 while (!tok_jmp(',')) {
670 readexpr();
671 ts_pop(&t);
672 bt[argc++] = TYPE_BT(&t);
674 tok_expect(')');
675 if (fi)
676 for (i = 0; i < fi->nargs; i++)
677 bt[i] = TYPE_BT(&fi->args[i]);
678 o_call(argc, bt, fi ? TYPE_BT(&fi->ret) : 4 | BT_SIGNED);
679 if (fi)
680 ts_push(&fi->ret);
681 else
682 ts_push_bt(4 | BT_SIGNED);
685 static void readpost(void)
687 readprimary();
688 while (1) {
689 if (!tok_jmp('[')) {
690 struct type t;
691 ts_pop(&t);
692 readexpr();
693 ts_pop(NULL);
694 tok_expect(']');
695 array2ptr(&t);
696 t.ptr--;
697 arrayderef(&t);
698 ts_push(&t);
699 continue;
701 if (!tok_jmp('(')) {
702 readcall();
703 continue;
705 if (!tok_jmp(TOK2("++"))) {
706 inc_post(o_add);
707 continue;
709 if (!tok_jmp(TOK2("--"))) {
710 inc_post(o_sub);
711 continue;
713 if (!tok_jmp('.')) {
714 o_addr();
715 readfield();
716 continue;
718 if (!tok_jmp(TOK2("->"))) {
719 readfield();
720 continue;
722 break;
726 static void inc_pre(void (*op)(void))
728 unsigned bt;
729 readpre();
730 bt = TYPE_BT(&ts[nts - 1]);
731 o_tmpcopy();
732 o_num(1, 4);
733 ts_push_bt(bt);
734 ts_push_bt(bt);
735 ts_binop_add(op);
736 ts_pop(NULL);
737 o_assign(bt);
740 static void readpre(void)
742 if (!tok_jmp('&')) {
743 struct type type;
744 readpre();
745 ts_pop(&type);
746 if (!(type.flags & T_FUNC) && !type.ptr)
747 type.ptr++;
748 ts_push(&type);
749 o_addr();
750 return;
752 if (!tok_jmp('*')) {
753 struct type t;
754 readpre();
755 ts_pop(&t);
756 array2ptr(&t);
757 if (!(t.flags & T_FUNC) || t.ptr > 0) {
758 t.ptr--;
759 o_deref(TYPE_BT(&t));
761 ts_push(&t);
762 return;
764 if (!tok_jmp('!')) {
765 struct type type;
766 readpre();
767 ts_pop(&type);
768 o_lnot();
769 ts_push_bt(4 | BT_SIGNED);
770 return;
772 if (!tok_jmp('-')) {
773 readpre();
774 o_neg();
775 return;
777 if (!tok_jmp('~')) {
778 readpre();
779 o_not();
780 return;
782 if (!tok_jmp(TOK2("++"))) {
783 inc_pre(o_add);
784 return;
786 if (!tok_jmp(TOK2("--"))) {
787 inc_pre(o_sub);
788 return;
790 if (!tok_jmp(TOK_SIZEOF)) {
791 struct type t;
792 int op = !tok_jmp('(');
793 if (readtype(&t)) {
794 int nogen = !o_nogen();
795 readexpr();
796 if (nogen)
797 o_dogen();
798 ts_pop(&t);
799 o_tmpdrop(1);
801 ts_push_bt(4);
802 o_num(type_totsz(&t), 4);
803 if (op)
804 tok_expect(')');
805 return;
807 readpost();
810 static void readmul(void)
812 readpre();
813 while (1) {
814 if (!tok_jmp('*')) {
815 readpre();
816 ts_binop(o_mul);
817 continue;
819 if (!tok_jmp('/')) {
820 readpre();
821 ts_binop(o_div);
822 continue;
824 if (!tok_jmp('%')) {
825 readpre();
826 ts_binop(o_mod);
827 continue;
829 break;
833 static void readadd(void)
835 readmul();
836 while (1) {
837 if (!tok_jmp('+')) {
838 readmul();
839 ts_binop_add(o_add);
840 continue;
842 if (!tok_jmp('-')) {
843 readmul();
844 ts_binop_add(o_sub);
845 continue;
847 break;
851 static void shift(void (*op)(void))
853 struct type t;
854 readadd();
855 ts_pop(NULL);
856 ts_pop(&t);
857 op();
858 ts_push_bt(TYPE_BT(&t));
861 static void readshift(void)
863 readadd();
864 while (1) {
865 if (!tok_jmp(TOK2("<<"))) {
866 shift(o_shl);
867 continue;
869 if (!tok_jmp(TOK2(">>"))) {
870 shift(o_shr);
871 continue;
873 break;
877 static void cmp(void (*op)(void))
879 readshift();
880 ts_pop(NULL);
881 ts_pop(NULL);
882 op();
883 ts_push_bt(4 | BT_SIGNED);
886 static void readcmp(void)
888 readshift();
889 while (1) {
890 if (!tok_jmp('<')) {
891 cmp(o_lt);
892 continue;
894 if (!tok_jmp('>')) {
895 cmp(o_gt);
896 continue;
898 if (!tok_jmp(TOK2("<="))) {
899 cmp(o_le);
900 continue;
902 if (!tok_jmp(TOK2(">="))) {
903 cmp(o_ge);
904 continue;
906 break;
910 static void eq(void (*op)(void))
912 readcmp();
913 ts_pop(NULL);
914 ts_pop(NULL);
915 op();
916 ts_push_bt(4 | BT_SIGNED);
919 static void readeq(void)
921 readcmp();
922 while (1) {
923 if (!tok_jmp(TOK2("=="))) {
924 eq(o_eq);
925 continue;
927 if (!tok_jmp(TOK2("!="))) {
928 eq(o_neq);
929 continue;
931 break;
935 static void readbitand(void)
937 readeq();
938 while (!tok_jmp('&')) {
939 readeq();
940 ts_binop(o_and);
944 static void readxor(void)
946 readbitand();
947 while (!tok_jmp('^')) {
948 readbitand();
949 ts_binop(o_xor);
953 static void readbitor(void)
955 readxor();
956 while (!tok_jmp('|')) {
957 readxor();
958 ts_binop(o_or);
962 #define MAXCOND (1 << 7)
964 static void readand(void)
966 long conds[MAXCOND];
967 int nconds = 0;
968 long passed;
969 int i;
970 readbitor();
971 if (tok_see() != TOK2("&&"))
972 return;
973 o_fork();
974 conds[nconds++] = o_jz(0);
975 ts_pop(NULL);
976 while (!tok_jmp(TOK2("&&"))) {
977 readbitor();
978 conds[nconds++] = o_jz(0);
979 ts_pop(NULL);
981 o_num(1, 4 | BT_SIGNED);
982 o_forkpush();
983 passed = o_jmp(0);
984 for (i = 0; i < nconds; i++)
985 o_filljmp(conds[i]);
986 o_num(0, 4 | BT_SIGNED);
987 o_forkpush();
988 o_forkjoin();
989 o_filljmp(passed);
990 ts_push_bt(4 | BT_SIGNED);
993 static void reador(void)
995 long conds[MAXCOND];
996 int nconds = 0;
997 long failed;
998 int i;
999 readand();
1000 if (tok_see() != TOK2("||"))
1001 return;
1002 o_fork();
1003 conds[nconds++] = o_jnz(0);
1004 ts_pop(NULL);
1005 while (!tok_jmp(TOK2("||"))) {
1006 readand();
1007 conds[nconds++] = o_jnz(0);
1008 ts_pop(NULL);
1010 o_num(0, 4 | BT_SIGNED);
1011 o_forkpush();
1012 failed = o_jmp(0);
1013 for (i = 0; i < nconds; i++)
1014 o_filljmp(conds[i]);
1015 o_num(1, 4 | BT_SIGNED);
1016 o_forkpush();
1017 o_forkjoin();
1018 o_filljmp(failed);
1019 ts_push_bt(4 | BT_SIGNED);
1022 static int readcexpr_const(void)
1024 long c;
1025 int nogen;
1026 if (o_popnum(&c))
1027 return -1;
1028 if (!c)
1029 nogen = !o_nogen();
1030 reador();
1031 ts_pop(NULL);
1032 tok_expect(':');
1033 if (c) {
1034 nogen = !o_nogen();
1035 } else {
1036 if (nogen)
1037 o_dogen();
1038 o_tmpdrop(1);
1040 reador();
1041 if (c) {
1042 if (nogen)
1043 o_dogen();
1044 o_tmpdrop(1);
1046 return 0;
1049 static void readcexpr(void)
1051 long l1, l2;
1052 reador();
1053 if (tok_jmp('?'))
1054 return;
1055 ncexpr++;
1056 ts_pop(NULL);
1057 o_fork();
1058 if (readcexpr_const()) {
1059 l1 = o_jz(0);
1060 reador();
1061 o_forkpush();
1062 l2 = o_jmp(0);
1063 ts_pop(NULL);
1065 tok_expect(':');
1066 o_filljmp(l1);
1067 reador();
1068 o_forkpush();
1069 o_forkjoin();
1070 o_filljmp(l2);
1072 ncexpr--;
1075 static void opassign(void (*bop)(void (*op)(void)), void (*op)(void))
1077 unsigned bt = TYPE_BT(&ts[nts - 1]);
1078 o_tmpcopy();
1079 readexpr();
1080 bop(op);
1081 ts_pop(NULL);
1082 o_assign(bt);
1085 static void doassign(void)
1087 struct type t;
1088 ts_pop(&t);
1089 if (!t.ptr && t.flags & T_STRUCT)
1090 o_memcpy(type_totsz(&t));
1091 else
1092 o_assign(TYPE_BT(&ts[nts - 1]));
1095 static void readexpr(void)
1097 readcexpr();
1098 if (!tok_jmp('=')) {
1099 readexpr();
1100 doassign();
1101 return;
1103 if (!tok_jmp(TOK2("+="))) {
1104 opassign(ts_binop_add, o_add);
1105 return;
1107 if (!tok_jmp(TOK2("-="))) {
1108 opassign(ts_binop_add, o_sub);
1109 return;
1111 if (!tok_jmp(TOK2("*="))) {
1112 opassign(ts_binop, o_mul);
1113 return;
1115 if (!tok_jmp(TOK2("/="))) {
1116 opassign(ts_binop, o_div);
1117 return;
1119 if (!tok_jmp(TOK2("%="))) {
1120 opassign(ts_binop, o_mod);
1121 return;
1123 if (!tok_jmp(TOK3("<<="))) {
1124 opassign(ts_binop, o_shl);
1125 return;
1127 if (!tok_jmp(TOK3(">>="))) {
1128 opassign(ts_binop, o_shr);
1129 return;
1131 if (!tok_jmp(TOK3("&="))) {
1132 opassign(ts_binop, o_and);
1133 return;
1135 if (!tok_jmp(TOK3("|="))) {
1136 opassign(ts_binop, o_or);
1137 return;
1139 if (!tok_jmp(TOK3("^="))) {
1140 opassign(ts_binop, o_xor);
1141 return;
1145 static void readestmt(void)
1147 do {
1148 o_tmpdrop(-1);
1149 nts = 0;
1150 readexpr();
1151 } while (!tok_jmp(','));
1154 static void o_localoff(long addr, int off, unsigned bt)
1156 o_local(addr, bt);
1157 if (off) {
1158 o_addr();
1159 o_num(off, 4);
1160 o_add();
1161 o_deref(bt);
1165 static struct type *innertype(struct type *t)
1167 if (t->flags & T_ARRAY && !t->ptr)
1168 return innertype(&arrays[t->id].type);
1169 return t;
1172 static void initexpr(struct type *t, int off, void *obj,
1173 void (*set)(void *obj, int off, struct type *t))
1175 if (tok_jmp('{')) {
1176 set(obj, off, t);
1177 return;
1179 if (!t->ptr && t->flags & T_STRUCT) {
1180 struct structinfo *si = &structs[t->id];
1181 int i;
1182 for (i = 0; i < si->nfields; i++) {
1183 struct name *field = &si->fields[i];
1184 if (!tok_jmp('.')) {
1185 tok_expect(TOK_NAME);
1186 field = struct_field(t->id, tok_id());
1187 tok_expect('=');
1189 initexpr(&field->type, off + field->addr, obj, set);
1190 if (tok_jmp(',') || tok_see() == '}')
1191 break;
1193 } else if (t->flags & T_ARRAY) {
1194 struct type *t_de = &arrays[t->id].type;
1195 int i;
1196 for (i = 0; ; i++) {
1197 long idx = i;
1198 struct type *it = t_de;
1199 if (!tok_jmp('[')) {
1200 readexpr();
1201 o_popnum(&idx);
1202 ts_pop(NULL);
1203 tok_expect(']');
1204 tok_expect('=');
1206 if (tok_see() != '{')
1207 it = innertype(t_de);
1208 initexpr(it, off + type_totsz(it) * idx, obj, set);
1209 if (tok_jmp(',') || tok_see() == '}')
1210 break;
1213 tok_expect('}');
1216 static void jumpbrace(void)
1218 int depth = 0;
1219 while (tok_see() != '}' || depth--)
1220 if (tok_get() == '{')
1221 depth++;
1222 tok_expect('}');
1225 static int initsize(void)
1227 long addr = tok_addr();
1228 int n = 0;
1229 if (!tok_jmp(TOK_STR)) {
1230 n = tok_str(NULL);
1231 tok_jump(addr);
1232 return n;
1234 o_nogen();
1235 tok_expect('{');
1236 while (tok_jmp('}')) {
1237 long idx = n;
1238 if (!tok_jmp('[')) {
1239 readexpr();
1240 o_popnum(&idx);
1241 ts_pop(NULL);
1242 tok_expect(']');
1243 tok_expect('=');
1245 if (n < idx + 1)
1246 n = idx + 1;
1247 while (tok_see() != '}' && tok_see() != ',')
1248 if (tok_get() == '{')
1249 jumpbrace();
1250 tok_jmp(',');
1252 o_dogen();
1253 tok_jump(addr);
1254 return n;
1257 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1259 static void globalinit(void *obj, int off, struct type *t)
1261 long addr = *(long *) obj;
1262 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1263 struct type *t_de = &arrays[t->id].type;
1264 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1265 char buf[BUFSIZE];
1266 int len;
1267 tok_expect(TOK_STR);
1268 len = tok_str(buf);
1269 out_datcpy(addr, off, buf, len);
1270 return;
1273 readexpr();
1274 o_datset(addr, off, TYPE_BT(t));
1275 ts_pop(NULL);
1278 static void globaldef(void *data, struct name *name, unsigned flags)
1280 struct type *t = &name->type;
1281 char *varname = flags & F_STATIC ? NULL : name->name;
1282 int sz;
1283 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1284 arrays[t->id].n = initsize();
1285 sz = type_totsz(t);
1286 if (flags & F_EXTERN || t->flags & T_FUNC && !t->ptr)
1287 name->unused = 1;
1288 else if (flags & F_INIT)
1289 name->addr = out_mkdat(varname, NULL, sz, F_GLOBAL(flags));
1290 else
1291 name->addr = out_mkvar(varname, sz, F_GLOBAL(flags));
1292 global_add(name);
1293 if (flags & F_INIT)
1294 initexpr(t, 0, &name->addr, globalinit);
1297 static void localinit(void *obj, int off, struct type *t)
1299 long addr = *(long *) obj;
1300 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1301 struct type *t_de = &arrays[t->id].type;
1302 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1303 char buf[BUFSIZE];
1304 int len;
1305 tok_expect(TOK_STR);
1306 len = tok_str(buf);
1307 o_localoff(addr, off, TYPE_BT(t));
1308 o_symaddr(out_mkdat(NULL, buf, len, 0), TYPE_BT(t));
1309 o_memcpy(len);
1310 o_tmpdrop(1);
1311 return;
1314 o_localoff(addr, off, TYPE_BT(t));
1315 ts_push(t);
1316 readexpr();
1317 doassign();
1318 ts_pop(NULL);
1319 o_tmpdrop(1);
1322 static void localdef(void *data, struct name *name, unsigned flags)
1324 struct type *t = &name->type;
1325 if (flags & (F_STATIC | F_EXTERN)) {
1326 globaldef(data, name, flags);
1327 return;
1329 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1330 arrays[t->id].n = initsize();
1331 name->addr = o_mklocal(type_totsz(&name->type));
1332 local_add(name);
1333 if (flags & F_INIT) {
1334 if (t->flags & (T_ARRAY | T_STRUCT) && !t->ptr) {
1335 o_local(name->addr, TYPE_BT(t));
1336 o_memset(0, type_totsz(t));
1337 o_tmpdrop(1);
1339 initexpr(t, 0, &name->addr, localinit);
1343 static void funcdef(char *name, struct type *type, struct name *args,
1344 int nargs, unsigned flags)
1346 struct name global;
1347 int i;
1348 strcpy(global.name, name);
1349 memcpy(&global.type, type, sizeof(*type));
1350 global.addr = o_func_beg(name, F_GLOBAL(flags));
1351 global.unused = 0;
1352 global_add(&global);
1353 ret_bt = TYPE_BT(&funcs[type->id].ret);
1354 for (i = 0; i < nargs; i++) {
1355 args[i].addr = o_arg(i, type_totsz(&args[i].type));
1356 local_add(&args[i]);
1360 static int readargs(struct name *args)
1362 int nargs = 0;
1363 tok_expect('(');
1364 while (tok_see() != ')') {
1365 if (!tok_jmp(TOK3("...")))
1366 break;
1367 readname(&args[nargs].type, args[nargs].name, NULL, 0);
1368 array2ptr(&args[nargs].type);
1369 nargs++;
1370 if (tok_jmp(','))
1371 break;
1373 tok_expect(')');
1374 if (nargs == 1 && !TYPE_BT(&args[0].type))
1375 return 0;
1376 return nargs;
1379 static int readname(struct type *main, char *name,
1380 struct type *base, unsigned flags)
1382 struct type tpool[3];
1383 int npool = 0;
1384 struct type *type = &tpool[npool++];
1385 struct type *func = NULL;
1386 struct type *ret = NULL;
1387 int arsz[10];
1388 int nar = 0;
1389 int i;
1390 memset(tpool, 0, sizeof(tpool));
1391 if (name)
1392 *name = '\0';
1393 if (!base) {
1394 if (basetype(type, &flags))
1395 return 1;
1396 } else {
1397 memcpy(type, base, sizeof(*base));
1399 readptrs(type);
1400 if (!tok_jmp('(')) {
1401 ret = type;
1402 type = &tpool[npool++];
1403 func = type;
1404 readptrs(type);
1406 if (!tok_jmp(TOK_NAME) && name)
1407 strcpy(name, tok_id());
1408 while (!tok_jmp('[')) {
1409 long n = 0;
1410 if (tok_jmp(']')) {
1411 readexpr();
1412 ts_pop(NULL);
1413 if (o_popnum(&n))
1414 err("const expr expected\n");
1415 tok_expect(']');
1417 arsz[nar++] = n;
1419 for (i = nar - 1; i >= 0; i--) {
1420 type->id = array_add(type, arsz[i]);
1421 if (type->flags & T_FUNC)
1422 func = &arrays[type->id].type;
1423 type->flags = T_ARRAY;
1424 type->bt = 8;
1425 type->ptr = 0;
1427 if (func)
1428 tok_expect(')');
1429 if (tok_see() == '(') {
1430 struct name args[MAXARGS];
1431 int nargs = readargs(args);
1432 int fdef = !func;
1433 if (!func) {
1434 ret = type;
1435 type = &tpool[npool++];
1436 func = type;
1438 func->flags = T_FUNC;
1439 func->bt = 8;
1440 func->id = func_create(ret, args, nargs);
1441 if (fdef && tok_see() == '{') {
1442 funcdef(name, func, args, nargs, flags);
1443 return 1;
1446 memcpy(main, type, sizeof(*type));
1447 return 0;
1450 static int readdefs(void (*def)(void *data, struct name *name, unsigned flags),
1451 void *data)
1453 struct type base;
1454 unsigned flags;
1455 if (basetype(&base, &flags))
1456 return 1;
1457 while (tok_see() != ';' && tok_see() != '{') {
1458 struct name name;
1459 name.unused = 0;
1460 if (readname(&name.type, name.name, &base, flags))
1461 break;
1462 if (!tok_jmp('='))
1463 flags |= F_INIT;
1464 def(data, &name, flags);
1465 tok_jmp(',');
1467 return 0;
1470 static void typedefdef(void *data, struct name *name, unsigned flags)
1472 typedef_add(name->name, &name->type);
1475 static void readstmt(void);
1477 #define MAXCASES (1 << 7)
1479 static void readswitch(void)
1481 int break_beg = nbreaks;
1482 long val_addr = o_mklocal(8);
1483 long matched[MAXCASES];
1484 int nmatched = 0;
1485 struct type t;
1486 long next;
1487 int ref = 1;
1488 int i;
1489 tok_expect('(');
1490 readexpr();
1491 ts_pop(&t);
1492 o_local(val_addr, TYPE_BT(&t));
1493 o_tmpswap();
1494 o_assign(TYPE_BT(&t));
1495 o_tmpdrop(1);
1496 tok_expect(')');
1497 tok_expect('{');
1498 while (tok_jmp('}')) {
1499 int n = 0;
1500 while (tok_see() == TOK_CASE || tok_see() == TOK_DEFAULT) {
1501 if (n++ > 0)
1502 matched[nmatched++] = o_jmp(0);
1503 if (!ref++)
1504 o_filljmp(next);
1505 if (!tok_jmp(TOK_CASE)) {
1506 caseexpr = 1;
1507 readexpr();
1508 caseexpr = 0;
1509 o_local(val_addr, TYPE_BT(&t));
1510 o_eq();
1511 next = o_jz(0);
1512 ref = 0;
1513 tok_expect(':');
1514 o_tmpdrop(1);
1515 ts_pop(NULL);
1516 continue;
1518 if (!tok_jmp(TOK_DEFAULT)) {
1519 tok_expect(':');
1520 continue;
1523 for (i = 0; i < nmatched; i++)
1524 o_filljmp(matched[i]);
1525 nmatched = 0;
1526 readstmt();
1528 o_rmlocal(val_addr, 8);
1529 if (!ref++)
1530 o_filljmp(next);
1531 break_fill(o_mklabel(), break_beg);
1534 #define MAXGOTO (1 << 10)
1536 static struct gotoinfo {
1537 char name[NAMELEN];
1538 long addr;
1539 } gotos[MAXGOTO];
1540 static int ngotos;
1542 static struct labelinfo {
1543 char name[NAMELEN];
1544 long addr;
1545 } labels[MAXGOTO];
1546 static int nlabels;
1548 static void goto_add(char *name)
1550 strcpy(gotos[ngotos].name, name);
1551 gotos[ngotos++].addr = o_jmp(0);
1554 static void label_add(char *name)
1556 strcpy(labels[nlabels].name, name);
1557 labels[nlabels++].addr = o_mklabel();
1560 static void goto_fill(void)
1562 int i, j;
1563 for (i = 0; i < ngotos; i++)
1564 for (j = 0; j < nlabels; j++)
1565 if (!strcmp(gotos[i].name, labels[j].name)) {
1566 o_filljmp2(gotos[i].addr, labels[j].addr);
1567 break;
1571 static void readstmt(void)
1573 o_tmpdrop(-1);
1574 nts = 0;
1575 if (!tok_jmp('{')) {
1576 int _nlocals = nlocals;
1577 int _nglobals = nglobals;
1578 int _nenums = nenums;
1579 int _ntypedefs = ntypedefs;
1580 int _nstructs = nstructs;
1581 int _nfuncs = nfuncs;
1582 int _narrays = narrays;
1583 while (tok_jmp('}'))
1584 readstmt();
1585 nlocals = _nlocals;
1586 nenums = _nenums;
1587 ntypedefs = _ntypedefs;
1588 nstructs = _nstructs;
1589 nfuncs = _nfuncs;
1590 narrays = _narrays;
1591 nglobals = _nglobals;
1592 return;
1594 if (!readdefs(localdef, NULL)) {
1595 tok_expect(';');
1596 return;
1598 if (!tok_jmp(TOK_TYPEDEF)) {
1599 readdefs(typedefdef, NULL);
1600 tok_expect(';');
1601 return;
1603 if (!tok_jmp(TOK_IF)) {
1604 long l1, l2;
1605 tok_expect('(');
1606 readexpr();
1607 tok_expect(')');
1608 l1 = o_jz(0);
1609 readstmt();
1610 if (!tok_jmp(TOK_ELSE)) {
1611 l2 = o_jmp(0);
1612 o_filljmp(l1);
1613 readstmt();
1614 o_filljmp(l2);
1615 } else {
1616 o_filljmp(l1);
1618 return;
1620 if (!tok_jmp(TOK_WHILE)) {
1621 long l1, l2;
1622 int break_beg = nbreaks;
1623 int continue_beg = ncontinues;
1624 l1 = o_mklabel();
1625 tok_expect('(');
1626 readexpr();
1627 tok_expect(')');
1628 l2 = o_jz(0);
1629 readstmt();
1630 o_jmp(l1);
1631 o_filljmp(l2);
1632 break_fill(o_mklabel(), break_beg);
1633 continue_fill(l1, continue_beg);
1634 return;
1636 if (!tok_jmp(TOK_DO)) {
1637 long l1, l2;
1638 int break_beg = nbreaks;
1639 int continue_beg = ncontinues;
1640 l1 = o_mklabel();
1641 readstmt();
1642 tok_expect(TOK_WHILE);
1643 tok_expect('(');
1644 l2 = o_mklabel();
1645 readexpr();
1646 o_jnz(l1);
1647 tok_expect(')');
1648 break_fill(o_mklabel(), break_beg);
1649 continue_fill(l2, continue_beg);
1650 return;
1652 if (!tok_jmp(TOK_FOR)) {
1653 long l_check, l_jump, j_fail, j_pass;
1654 int break_beg = nbreaks;
1655 int continue_beg = ncontinues;
1656 int has_cond = 0;
1657 tok_expect('(');
1658 if (tok_see() != ';')
1659 readestmt();
1660 tok_expect(';');
1661 l_check = o_mklabel();
1662 if (tok_see() != ';') {
1663 readestmt();
1664 j_fail = o_jz(0);
1665 has_cond = 1;
1667 tok_expect(';');
1668 j_pass = o_jmp(0);
1669 l_jump = o_mklabel();
1670 if (tok_see() != ')')
1671 readestmt();
1672 tok_expect(')');
1673 o_jmp(l_check);
1674 o_filljmp(j_pass);
1675 readstmt();
1676 o_jmp(l_jump);
1677 if (has_cond)
1678 o_filljmp(j_fail);
1679 break_fill(o_mklabel(), break_beg);
1680 continue_fill(l_jump, continue_beg);
1681 return;
1683 if (!tok_jmp(TOK_SWITCH)) {
1684 readswitch();
1685 return;
1687 if (!tok_jmp(TOK_RETURN)) {
1688 int ret = tok_see() != ';';
1689 if (ret)
1690 readexpr();
1691 tok_expect(';');
1692 o_ret(ret_bt);
1693 return;
1695 if (!tok_jmp(TOK_BREAK)) {
1696 tok_expect(';');
1697 breaks[nbreaks++] = o_jmp(0);
1698 return;
1700 if (!tok_jmp(TOK_CONTINUE)) {
1701 tok_expect(';');
1702 continues[ncontinues++] = o_jmp(0);
1703 return;
1705 if (!tok_jmp(TOK_GOTO)) {
1706 tok_expect(TOK_NAME);
1707 goto_add(tok_id());
1708 tok_expect(';');
1709 return;
1711 readestmt();
1712 /* labels */
1713 if (!tok_jmp(':')) {
1714 label_add(tok_id());
1715 return;
1717 tok_expect(';');
1720 static void readdecl(void)
1722 if (!tok_jmp(TOK_TYPEDEF)) {
1723 readdefs(typedefdef, NULL);
1724 tok_expect(';');
1725 return;
1727 readdefs(globaldef, NULL);
1728 if (tok_see() == '{') {
1729 readstmt();
1730 goto_fill();
1731 o_func_end();
1732 nlocals = 0;
1733 ngotos = 0;
1734 nlabels = 0;
1735 return;
1737 tok_expect(';');
1740 static void parse(void)
1742 while (tok_see() != TOK_EOF)
1743 readdecl();
1746 int main(int argc, char *argv[])
1748 char obj[128];
1749 int ofd;
1750 int i = 1;
1751 while (i < argc && argv[i][0] == '-') {
1752 if (argv[i][1] == 'I')
1753 cpp_addpath(argv[i][2] ? argv[i] + 2 : argv[++i]);
1754 if (argv[i][1] == 'D') {
1755 char *name = argv[i] + 2;
1756 char *def = "";
1757 char *eq = strchr(name, '=');
1758 if (eq) {
1759 *eq = '\0';
1760 def = eq + 1;
1762 cpp_define(name, def);
1764 i++;
1766 if (i == argc)
1767 die("neatcc: no file given\n");
1768 if (cpp_init(argv[i]))
1769 die("neatcc: cannot open input file\n");
1770 parse();
1771 strcpy(obj, argv[i]);
1772 obj[strlen(obj) - 1] = 'o';
1773 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1774 out_write(ofd);
1775 close(ofd);
1776 return 0;