ncc: print usage in ncc -h
[neatcc.git] / int.c
blob8698afcd0872c81b591d71709121b9ff43804ffa
1 /* neatcc intermediate code generation */
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include "ncc.h"
7 static struct ic *ic; /* intermediate code */
8 static long ic_n, ic_sz; /* number of instructions in ic[] */
9 static long iv[NTMPS]; /* operand stack */
10 static long iv_n; /* number of values in iv[] */
11 static long *lab_loc; /* label locations */
12 static long lab_n, lab_sz; /* number of labels in lab_loc[] */
13 static long lab_last; /* the last label target */
15 static int io_num(void);
16 static int io_mul2(void);
17 static int io_cmp(void);
18 static int io_jmp(void);
19 static int io_addr(void);
20 static int io_loc(void);
21 static int io_imm(void);
22 static int io_call(void);
23 static void io_deadcode(void);
25 static void iv_put(long n);
27 static struct ic *ic_put(long op, long arg1, long arg2, long arg3)
29 struct ic *c;
30 if (ic_n == ic_sz) {
31 ic_sz = MAX(128, ic_sz * 2);
32 ic = mextend(ic, ic_n, ic_sz, sizeof(*ic));
34 c = &ic[ic_n++];
35 c->op = op;
36 c->a1 = arg1;
37 c->a2 = arg2;
38 c->a3 = arg3;
39 if (op & O_OUT)
40 iv_put(ic_n - 1);
41 return c;
44 static void ic_back(long pos)
46 int i;
47 for (i = pos; i < ic_n; i++)
48 if (ic[i].op & O_CALL)
49 free(ic[i].args);
50 ic_n = pos;
53 static long iv_pop(void)
55 return iv[--iv_n];
58 static long iv_get(int n)
60 return iv[iv_n - n - 1];
63 static void iv_put(long n)
65 iv[iv_n++] = n;
68 static void iv_drop(int n)
70 iv_n = MAX(0, iv_n - n);
73 static void iv_swap(int x, int y)
75 long v = iv[iv_n - x - 1];
76 iv[iv_n - x - 1] = iv[iv_n - y - 1];
77 iv[iv_n - y - 1] = v;
80 static void iv_dup(void)
82 iv[iv_n] = iv[iv_n - 1];
83 iv_n++;
86 void o_num(long n)
88 ic_put(O_MOV | O_NUM, n, 0, 0);
91 void o_local(long id)
93 ic_put(O_MOV | O_LOC, id, 0, 0);
96 void o_sym(char *sym)
98 ic_put(O_MOV | O_SYM, out_sym(sym), 0, 0);
101 void o_tmpdrop(int n)
103 iv_drop(n >= 0 ? n : iv_n);
106 void o_tmpswap(void)
108 iv_swap(0, 1);
111 void o_tmpcopy(void)
113 iv_dup();
116 /* return one if the given value is constant */
117 static int ic_const(long iv)
119 long oc = O_C(ic[iv].op);
120 return oc & O_MOV && oc & (O_NUM | O_SYM | O_LOC);
123 /* return one if the given value is a simple load */
124 static int ic_load(long iv)
126 long oc = O_C(ic[iv].op);
127 int i;
128 if (oc & O_LD && oc & (O_NUM | O_SYM | O_LOC)) {
129 for (i = iv + 1; i < ic_n; i++)
130 if (ic[i].op & O_ST)
131 return 0;
132 return 1;
134 return 0;
137 void o_bop(long op)
139 int r1 = iv_pop();
140 int r2 = iv_pop();
141 /* load constants as late as possible */
142 if (opt(1) && ic_const(r2) && !ic_const(r1)) {
143 ic_put(ic[r2].op, ic[r2].a1, ic[r2].a2, ic[r2].a3);
144 r2 = iv_pop();
146 ic_put(op, r2, r1, 0);
147 if (opt(1)) {
148 io_num();
149 io_mul2();
150 io_addr();
151 io_imm();
155 void o_uop(long op)
157 int r1 = iv_pop();
158 ic_put(op, r1, 0, 0);
159 if (opt(1)) {
160 io_num();
161 io_cmp();
165 void o_assign(long bt)
167 int rv = iv_pop();
168 int lv = iv_pop();
169 /* load constants as late as possible */
170 if (opt(1) && (ic_const(lv) || ic_load(lv))) {
171 ic_put(ic[lv].op, ic[lv].a1, ic[lv].a2, ic[lv].a3);
172 lv = iv_pop();
174 ic_put(O_MK(O_ST | O_NUM, bt), rv, lv, 0);
175 iv_put(rv);
176 if (opt(1))
177 io_loc();
180 void o_deref(long bt)
182 int r1 = iv_pop();
183 ic_put(O_MK(O_LD | O_NUM, bt), r1, 0, 0);
184 if (opt(1))
185 io_loc();
188 void o_cast(long bt)
190 if (T_SZ(bt) != ULNG) {
191 int r1 = iv_pop();
192 ic_put(O_MK(O_MOV, bt), r1, 0, 0);
193 if (opt(1))
194 io_num();
198 void o_memcpy(void)
200 int r2 = iv_pop();
201 int r1 = iv_pop();
202 int r0 = iv_pop();
203 ic_put(O_MCPY, r0, r1, r2);
206 void o_memset(void)
208 int r2 = iv_pop();
209 int r1 = iv_pop();
210 int r0 = iv_pop();
211 ic_put(O_MSET, r0, r1, r2);
214 void o_call(int argc, int ret)
216 struct ic *c;
217 long *args = malloc(argc * sizeof(c->args[0]));
218 int r1, i;
219 for (i = argc - 1; i >= 0; --i)
220 args[i] = iv_pop();
221 for (i = argc - 1; i >= 0; --i) {
222 int iv = args[i];
223 /* load constants as late as possible */
224 if (opt(1) && (ic_const(iv) || ic_load(iv))) {
225 ic_put(ic[iv].op, ic[iv].a1, ic[iv].a2, ic[iv].a3);
226 args[i] = iv_pop();
229 r1 = iv_pop();
230 c = ic_put(O_CALL, r1, 0, argc);
231 c->args = args;
232 iv_drop(ret == 0);
233 if (opt(1))
234 io_call();
237 void o_ret(int ret)
239 if (!ret)
240 o_num(0);
241 ic_put(O_RET, iv_pop(), 0, 0);
244 void o_label(long id)
246 while (id >= lab_sz) {
247 lab_sz = MAX(128, lab_sz * 2);
248 lab_loc = mextend(lab_loc, lab_n, lab_sz, sizeof(*lab_loc));
250 while (lab_n <= id)
251 lab_loc[lab_n++] = -1;
252 lab_loc[id] = ic_n;
253 lab_last = ic_n;
256 void o_jmp(long id)
258 ic_put(O_JMP, 0, 0, id);
261 void o_jz(long id)
263 ic_put(O_JZ, iv_pop(), 0, id);
264 if (opt(1))
265 io_jmp();
268 int o_popnum(long *n)
270 if (ic_num(ic, iv_get(0), n))
271 return 1;
272 iv_drop(1);
273 return 0;
276 int o_popsym(long *sym, long *off)
278 if (ic_sym(ic, iv_get(0), sym, off))
279 return 1;
280 iv_drop(1);
281 return 0;
284 long o_mark(void)
286 return ic_n;
289 void o_back(long mark)
291 ic_back(mark);
294 void ic_get(struct ic **c, long *n)
296 int i;
297 if (!ic_n || ~ic[ic_n - 1].op & O_RET || lab_last == ic_n)
298 o_ret(0);
299 for (i = 0; i < ic_n; i++) /* filling branch targets */
300 if (ic[i].op & O_JXX)
301 ic[i].a3 = lab_loc[ic[i].a3];
302 io_deadcode(); /* removing dead code */
303 *c = ic;
304 *n = ic_n;
305 ic = NULL;
306 ic_n = 0;
307 ic_sz = 0;
308 iv_n = 0;
309 free(lab_loc);
310 lab_loc = NULL;
311 lab_n = 0;
312 lab_sz = 0;
313 lab_last = 0;
316 void ic_free(struct ic *ic)
318 if (ic->op & O_CALL)
319 free(ic->args);
322 /* intermediate code queries */
324 static long cb(long op, long a, long b)
326 switch (O_C(op)) {
327 case O_ADD:
328 return a + b;
329 case O_SUB:
330 return a - b;
331 case O_AND:
332 return a & b;
333 case O_OR:
334 return a | b;
335 case O_XOR:
336 return a ^ b;
337 case O_MUL:
338 return a * b;
339 case O_DIV:
340 return a / b;
341 case O_MOD:
342 return a % b;
343 case O_SHL:
344 return a << b;
345 case O_SHR:
346 return O_T(op) & T_MSIGN ? a >> b : (unsigned long) a >> b;
347 case O_LT:
348 return a < b;
349 case O_GT:
350 return a > b;
351 case O_LE:
352 return a <= b;
353 case O_GE:
354 return a >= b;
355 case O_EQ:
356 return a == b;
357 case O_NE:
358 return a != b;
360 return 0;
363 static long cu(int op, long i)
365 switch (O_C(op)) {
366 case O_NEG:
367 return -i;
368 case O_NOT:
369 return ~i;
370 case O_LNOT:
371 return !i;
373 return 0;
376 static long c_cast(long n, unsigned bt)
378 if (!(bt & T_MSIGN) && T_SZ(bt) != ULNG)
379 n &= ((1l << (long) (T_SZ(bt) * 8)) - 1);
380 if (bt & T_MSIGN && T_SZ(bt) != ULNG &&
381 n > (1l << (T_SZ(bt) * 8 - 1)))
382 n = -((1l << (T_SZ(bt) * 8)) - n);
383 return n;
386 int ic_num(struct ic *ic, long iv, long *n)
388 long n1, n2;
389 long oc = O_C(ic[iv].op);
390 long bt = O_T(ic[iv].op);
391 if (oc & O_MOV && oc & O_NUM) {
392 *n = ic[iv].a1;
393 return 0;
395 if (oc & O_BOP) {
396 if (ic_num(ic, ic[iv].a1, &n1))
397 return 1;
398 if (ic_num(ic, ic[iv].a2, &n2))
399 return 1;
400 *n = cb(ic[iv].op, n1, n2);
401 return 0;
403 if (oc & O_UOP) {
404 if (ic_num(ic, ic[iv].a1, &n1))
405 return 1;
406 *n = cu(ic[iv].op, n1);
407 return 0;
409 if (oc & O_MOV && !(oc & (O_NUM | O_LOC | O_SYM))) {
410 if (ic_num(ic, ic[iv].a1, &n1))
411 return 1;
412 *n = c_cast(n1, bt);
413 return 0;
415 return 1;
418 int ic_sym(struct ic *ic, long iv, long *sym, long *off)
420 long n;
421 long oc = O_C(ic[iv].op);
422 if (oc & O_MOV && oc & O_SYM) {
423 *sym = ic[iv].a1;
424 *off = ic[iv].a2;
425 return 0;
427 if (oc == O_ADD) {
428 if ((ic_sym(ic, ic[iv].a1, sym, off) ||
429 ic_num(ic, ic[iv].a2, &n)) &&
430 (ic_sym(ic, ic[iv].a2, sym, off) ||
431 ic_num(ic, ic[iv].a1, &n)))
432 return 1;
433 *off += n;
434 return 0;
436 if (oc == O_SUB) {
437 if (ic_sym(ic, ic[iv].a1, sym, off) ||
438 ic_num(ic, ic[iv].a2, &n))
439 return 1;
440 *off -= n;
441 return 0;
443 return 1;
446 static int ic_off(struct ic *ic, long iv, long *base_iv, long *off)
448 long n;
449 long oc = O_C(ic[iv].op);
450 if (oc == (O_ADD | O_NUM)) {
451 *base_iv = ic[iv].a1;
452 *off = ic[iv].a2;
453 return 0;
455 if (oc == (O_SUB | O_NUM)) {
456 *base_iv = ic[iv].a1;
457 *off = -ic[iv].a2;
458 return 0;
460 if (oc == O_ADD) {
461 if ((ic_off(ic, ic[iv].a1, base_iv, off) ||
462 ic_num(ic, ic[iv].a2, &n)) &&
463 (ic_off(ic, ic[iv].a2, base_iv, off) ||
464 ic_num(ic, ic[iv].a1, &n)))
465 return 1;
466 *off += n;
467 return 0;
469 if (oc == O_SUB) {
470 if (ic_off(ic, ic[iv].a1, base_iv, off) ||
471 ic_num(ic, ic[iv].a2, &n))
472 return 1;
473 *off -= n;
474 return 0;
476 *base_iv = iv;
477 *off = 0;
478 return 0;
481 /* number of register arguments */
482 int ic_regcnt(struct ic *ic)
484 long o = ic->op;
485 if (o & O_BOP)
486 return o & (O_NUM | O_SYM | O_LOC) ? 1 : 2;
487 if (o & O_UOP)
488 return o & (O_NUM | O_SYM | O_LOC) ? 0 : 1;
489 if (o & O_CALL)
490 return o & (O_NUM | O_SYM | O_LOC) ? 0 : 1;
491 if (o & O_MOV)
492 return o & (O_NUM | O_SYM | O_LOC) ? 0 : 1;
493 if (o & O_MEM)
494 return 3;
495 if (o & O_JMP)
496 return 0;
497 if (o & O_JZ)
498 return 1;
499 if (o & O_JCC)
500 return o & (O_NUM | O_SYM | O_LOC) ? 1 : 2;
501 if (o & O_RET)
502 return 1;
503 if (o & O_LD)
504 return ((o & O_NUM) != 0);
505 if (o & O_ST)
506 return 1 + ((o & O_NUM) != 0);
507 return 0;
511 * The returned array indicates the last instruction in
512 * which the value produced by each instruction is used.
514 long *ic_lastuse(struct ic *ic, long ic_n)
516 long *luse = calloc(ic_n, sizeof(luse[0]));
517 int i, j;
518 for (i = ic_n - 1; i >= 0; --i) {
519 int n = ic_regcnt(ic + i);
520 if (!luse[i])
521 if (!(ic[i].op & O_OUT) || ic[i].op & O_CALL)
522 luse[i] = -1;
523 if (!luse[i])
524 continue;
525 if (n >= 1 && !luse[ic[i].a1])
526 luse[ic[i].a1] = i;
527 if (n >= 2 && !luse[ic[i].a2])
528 luse[ic[i].a2] = i;
529 if (n >= 3 && !luse[ic[i].a3])
530 luse[ic[i].a3] = i;
531 if (ic[i].op & O_CALL)
532 for (j = 0; j < ic[i].a3; j++)
533 if (!luse[ic[i].args[j]])
534 luse[ic[i].args[j]] = i;
536 return luse;
539 /* intermediate code optimisations */
541 /* constant folding */
542 static int io_num(void)
544 long n;
545 if (!ic_num(ic, iv_get(0), &n)) {
546 iv_drop(1);
547 o_num(n);
548 return 0;
550 return 1;
553 static int log2a(unsigned long n)
555 int i = 0;
556 for (i = 0; i < LONGSZ * 8; i++)
557 if (n & (1u << i))
558 break;
559 if (i == LONGSZ * 8 || !(n >> (i + 1)))
560 return i;
561 return -1;
564 static long iv_num(long n)
566 o_num(n);
567 return iv_pop();
570 /* optimised multiplication operations for powers of two */
571 static int io_mul2(void)
573 long iv = iv_get(0);
574 long n, p;
575 long r1, r2;
576 long oc = O_C(ic[iv].op);
577 long bt = O_T(ic[iv].op);
578 if (!(oc & O_MUL))
579 return 1;
580 if (oc == O_MUL && !ic_num(ic, ic[iv].a1, &n)) {
581 long t = ic[iv].a1;
582 ic[iv].a1 = ic[iv].a2;
583 ic[iv].a2 = t;
585 if (ic_num(ic, ic[iv].a2, &n))
586 return 1;
587 p = log2a(n);
588 if (n && p < 0)
589 return 1;
590 if (oc == O_MUL) {
591 iv_drop(1);
592 if (n == 1) {
593 iv_put(ic[iv].a1);
594 return 0;
596 if (n == 0) {
597 o_num(0);
598 return 0;
600 r2 = iv_num(p);
601 ic_put(O_MK(O_SHL, ULNG), ic[iv].a1, r2, 0);
602 return 0;
604 if (oc == O_DIV && ~bt & T_MSIGN) {
605 iv_drop(1);
606 if (n == 1) {
607 iv_put(ic[iv].a1);
608 return 0;
610 r2 = iv_num(p);
611 ic_put(O_MK(O_SHR, ULNG), ic[iv].a1, r2, 0);
612 return 0;
614 if (oc == O_MOD && ~bt & T_MSIGN) {
615 iv_drop(1);
616 if (n == 1) {
617 o_num(0);
618 return 0;
620 r2 = iv_num(LONGSZ * 8 - p);
621 ic_put(O_MK(O_SHL, ULNG), ic[iv].a1, r2, 0);
622 r1 = iv_pop();
623 r2 = iv_num(LONGSZ * 8 - p);
624 ic_put(O_MK(O_SHR, ULNG), r1, r2, 0);
625 return 0;
627 return 1;
630 /* optimise comparison */
631 static int io_cmp(void)
633 long iv = iv_get(0);
634 long cmp = ic[iv].a1;
635 if (O_C(ic[iv].op) == O_LNOT && ic[cmp].op & O_CMP) {
636 iv_drop(1);
637 ic[cmp].op ^= 1;
638 iv_put(cmp);
639 return 0;
641 return 1;
644 /* optimise branch instructions after comparison */
645 static int io_jmp(void)
647 struct ic *c = &ic[ic_n - 1];
648 long oc = O_C(c->op);
649 if (oc & O_JZ && O_C(ic[c->a1].op) == O_LNOT) {
650 c->a1 = ic[c->a1].a1;
651 c->op ^= 1;
652 return 0;
654 if (oc & O_JZ && O_C(ic[c->a1].op) & O_CMP) {
655 long cop = (ic[c->a1].op & ~O_CMP) | O_JCC;
656 c->op = O_C(c->op) == O_JZ ? cop ^ 1 : cop;
657 c->a2 = ic[c->a1].a2;
658 c->a1 = ic[c->a1].a1;
659 return 0;
661 return 1;
664 /* optimise accessing locals or symbols with an offset */
665 static int io_addr(void)
667 long iv, off;
668 if (ic_off(ic, iv_get(0), &iv, &off) || iv == iv_get(0))
669 return 1;
670 if (ic[iv].op & O_MOV && ic[iv].op & O_LOC) {
671 iv_drop(1);
672 ic_put(O_MOV | O_LOC, ic[iv].a1, ic[iv].a2 + off, 0);
673 return 0;
675 if (ic[iv].op & O_MOV && ic[iv].op & O_SYM) {
676 iv_drop(1);
677 ic_put(O_MOV | O_SYM, ic[iv].a1, ic[iv].a2 + off, 0);
678 return 0;
680 return 1;
683 static int imm_ok(long op, long n, int arg)
685 long m[5];
686 if (i_reg(op | O_NUM, m + 0, m + 1, m + 2, m + 3, m + 4))
687 return 0;
688 return i_imm(m[arg], n);
691 /* optimise loading and storing locals */
692 static int io_loc(void)
694 struct ic *c = &ic[ic_n - 1];
695 long iv, off;
696 if (c->op & O_LD && c->op & O_NUM) {
697 if (ic_off(ic, c->a1, &iv, &off))
698 return 1;
699 if (ic[iv].op & O_MOV && ic[iv].op & O_LOC) {
700 c->op = (c->op & ~O_NUM) | O_LOC;
701 c->a1 = ic[iv].a1;
702 c->a2 += ic[iv].a2 + off;
703 return 0;
705 if (imm_ok(c->op, off, 2)) {
706 c->a1 = iv;
707 c->a2 += off;
709 return 0;
711 if (c->op & O_ST && c->op & O_NUM) {
712 if (ic_off(ic, c->a2, &iv, &off))
713 return 1;
714 if (ic[iv].op & O_MOV && ic[iv].op & O_LOC) {
715 c->op = (c->op & ~O_NUM) | O_LOC;
716 c->a2 = ic[iv].a1;
717 c->a3 += ic[iv].a2 + off;
718 return 0;
720 if (imm_ok(c->op, off, 3)) {
721 c->a2 = iv;
722 c->a3 += off;
724 return 0;
726 return 1;
729 /* use instruction immediates */
730 static int io_imm(void)
732 struct ic *c = &ic[ic_n - 1];
733 long oc = O_C(c->op);
734 long n;
735 if (oc & (O_NUM | O_LOC | O_SYM))
736 return 1;
737 if (oc == O_ADD || oc == O_MUL || oc == O_AND || oc == O_OR ||
738 oc == O_XOR || oc == O_EQ || oc == O_NE) {
739 if (!ic_num(ic, c->a1, &n)) {
740 long t = c->a1;
741 c->a1 = c->a2;
742 c->a2 = t;
745 if (oc == O_LT || oc == O_GE || oc == O_LE || oc == O_GT) {
746 if (!ic_num(ic, c->a1, &n)) {
747 int t = c->a1;
748 c->a1 = c->a2;
749 c->a2 = t;
750 c->op ^= 1;
753 if (oc & O_JCC && !ic_num(ic, c->a1, &n)) {
754 int t = c->a1;
755 c->a1 = c->a2;
756 c->a2 = t;
757 c->op ^= 1;
759 if (oc & O_JCC && !ic_num(ic, c->a2, &n) && imm_ok(c->op, n, 1)) {
760 c->op |= O_NUM;
761 c->a2 = n;
762 return 0;
764 if (!(oc & O_BOP) || ic_num(ic, c->a2, &n))
765 return 1;
766 if ((oc == O_ADD || oc == O_SUB || oc & O_SHL) && n == 0) {
767 iv_drop(1);
768 iv_put(c->a1);
769 return 0;
771 if (imm_ok(c->op, n, 2)) {
772 c->op |= O_NUM;
773 c->a2 = n;
774 return 0;
776 return 1;
779 /* calling symbols */
780 static int io_call(void)
782 struct ic *c = &ic[ic_n - 1];
783 long sym, off;
784 if (c->op & O_CALL && !ic_sym(ic, c->a1, &sym, &off) && !off) {
785 c->op |= O_SYM;
786 c->a1 = sym;
787 return 0;
789 return 1;
792 /* remove dead code */
793 static void io_deadcode(void)
795 char *live;
796 long *nidx;
797 long src = 0, dst = 0;
798 int i, j;
799 /* liveness analysis */
800 live = calloc(ic_n, sizeof(live[0]));
801 for (i = ic_n - 1; i >= 0; i--) {
802 int n = ic_regcnt(ic + i);
803 if (!(ic[i].op & O_OUT) || ic[i].op & O_CALL)
804 live[i] = 1;
805 if (!live[i])
806 continue;
807 if (n >= 1)
808 live[ic[i].a1] = 1;
809 if (n >= 2)
810 live[ic[i].a2] = 1;
811 if (n >= 3)
812 live[ic[i].a3] = 1;
813 if (ic[i].op & O_CALL)
814 for (j = 0; j < ic[i].a3; j++)
815 live[ic[i].args[j]] = 1;
817 /* the new indices of intermediate instructions */
818 nidx = calloc(ic_n, sizeof(nidx[0]));
819 while (src < ic_n) {
820 while (src < ic_n && !live[src]) {
821 nidx[src] = dst;
822 ic_free(&ic[src++]);
824 if (src < ic_n) {
825 nidx[src] = dst;
826 if (src != dst)
827 memcpy(ic + dst, ic + src, sizeof(ic[src]));
828 src++;
829 dst++;
832 ic_n = dst;
833 /* adjusting arguments and branch targets */
834 for (i = 0; i < ic_n; i++) {
835 int n = ic_regcnt(ic + i);
836 if (n >= 1)
837 ic[i].a1 = nidx[ic[i].a1];
838 if (n >= 2)
839 ic[i].a2 = nidx[ic[i].a2];
840 if (n >= 3)
841 ic[i].a3 = nidx[ic[i].a3];
842 if (ic[i].op & O_JXX)
843 ic[i].a3 = nidx[ic[i].a3];
844 if (ic[i].op & O_CALL)
845 for (j = 0; j < ic[i].a3; j++)
846 ic[i].args[j] = nidx[ic[i].args[j]];
848 free(live);
849 free(nidx);