Mercurial > hg > CbC > old > device
comparison mc-codegen.c @ 438:626d705471d5 lazy-branch
Unexecuted code in conditional. Lazy jmp code generation.
author | kono |
---|---|
date | Mon, 15 Nov 2004 20:33:30 +0900 |
parents | 49d4483d5110 |
children | 65e379ba36b8 |
comparison
equal
deleted
inserted
replaced
437:49d4483d5110 | 438:626d705471d5 |
---|---|
130 extern int | 130 extern int |
131 g_expr0(int e1) | 131 g_expr0(int e1) |
132 { | 132 { |
133 int e2,e3,t,d,t1; | 133 int e2,e3,t,d,t1; |
134 NMTBL *n; | 134 NMTBL *n; |
135 if (!control) return VOID; | |
135 | 136 |
136 code_gexpr(e1); | 137 code_gexpr(e1); |
137 | 138 |
138 e2 = cadr(e1); | 139 e2 = cadr(e1); |
139 switch (car(e1)){ | 140 switch (car(e1)){ |
425 g_expr0(caddr(e1)); | 426 g_expr0(caddr(e1)); |
426 } else { // gcc extenstion a?:DEF | 427 } else { // gcc extenstion a?:DEF |
427 bexpr(cadr(e1),0,e2); // value used | 428 bexpr(cadr(e1),0,e2); // value used |
428 } | 429 } |
429 t = code_get_fixed_creg(USE_CREG,d); | 430 t = code_get_fixed_creg(USE_CREG,d); |
430 jmp(e3=fwdlabel()); | 431 gen_jmp(e3=fwdlabel()); |
431 fwddef(e2); | 432 fwddef(e2); |
432 t1=g_expr0(cadddr(e1)); | 433 t1=g_expr0(cadddr(e1)); |
433 code_set_fixed_creg(t,1,d); | 434 code_set_fixed_creg(t,1,d); |
434 fwddef(e3); | 435 fwddef(e3); |
435 return t1; | 436 return t1; |
537 } | 538 } |
538 return op; | 539 return op; |
539 } | 540 } |
540 | 541 |
541 /* bexpr for value unused */ | 542 /* bexpr for value unused */ |
542 | 543 /* l1 ... label for branch */ |
543 extern void | 544 /* return 0 if l1 is not used, otherwise return l1 */ |
545 | |
546 extern int | |
544 bexpr_u(int e1, char cond, int l1) | 547 bexpr_u(int e1, char cond, int l1) |
545 { | 548 { |
546 int op = car(e1); | 549 int op = car(e1); |
547 if (chk) return; | 550 if (chk) return l1; |
548 // gexpr_init(); | 551 // gexpr_init(); |
549 switch(op) { | 552 switch(op) { |
550 case GT: case UGT: case GE: case UGE: case LT: | 553 case GT: case UGT: case GE: case UGE: case LT: |
551 case ULT: case LE: case ULE: | 554 case ULT: case LE: case ULE: |
552 case DOP+GT: case DOP+GE: case DOP+LT: case DOP+LE: | 555 case DOP+GT: case DOP+GE: case DOP+LT: case DOP+LE: |
553 case FOP+GT: case FOP+GE: case FOP+LT: case FOP+LE: | 556 case FOP+GT: case FOP+GE: case FOP+LT: case FOP+LE: |
554 case FOP+EQ: case FOP+NEQ: | 557 case FOP+EQ: case FOP+NEQ: |
555 case EQ: case NEQ: case DOP+EQ: case DOP+NEQ: | 558 case EQ: case NEQ: case DOP+EQ: case DOP+NEQ: |
556 if (car(caddr(e1))==CONST||(car(caddr(e1))==DCONST)|| | 559 if (car(caddr(e1))==CONST||(car(caddr(e1))==DCONST)|| |
557 car(caddr(e1))==FCONST) { | 560 car(caddr(e1))==FCONST) { |
558 b_expr(list3(rop_dual(op),caddr(e1),cadr(e1)),cond,l1,0); | 561 return b_expr(list3(rop_dual(op),caddr(e1),cadr(e1)),cond,l1,0); |
559 return; | 562 } |
560 } | 563 } |
561 } | 564 return b_expr(e1,cond,l1,0); |
562 b_expr(e1,cond,l1,0); | |
563 } | 565 } |
564 | 566 |
565 /* bexpr for value used */ | 567 /* bexpr for value used */ |
566 | 568 |
567 extern void | 569 extern int |
568 bexpr(int e1, char cond, int l1) | 570 bexpr(int e1, char cond, int l1) |
569 { | 571 { |
570 int uses = use; use=1; | 572 int uses = use; use=1; |
571 bexpr_u(e1, cond, l1); | 573 l1 = bexpr_u(e1, cond, l1); |
572 use = uses; | 574 use = uses; |
575 return l1; | |
573 } | 576 } |
574 | 577 |
575 /* branch expression generator */ | 578 /* branch expression generator */ |
576 /* if (cond?e1:!e1) goto l1 */ | 579 /* if (cond?e1:!e1) goto l1 */ |
577 /* 1 or 0 is return for code_bool */ | 580 /* 1 or 0 is return for code_bool */ |
578 | 581 |
579 extern void | 582 extern int |
580 b_expr(int e1, char cond, int l1,int err) | 583 b_expr(int e1, char cond, int l1,int err) |
581 { | 584 { |
582 int e2,l2,t; | 585 int e2,l2,t; |
583 if (!control) return; | 586 if (!control) return l1; |
584 l2 = 0; | 587 l2 = 0; |
585 e2=cadr(e1); | 588 e2=cadr(e1); |
586 switch(car(e1)) { | 589 switch(car(e1)) { |
587 case LNOT: | 590 case LNOT: |
588 b_expr(e2,!cond,l1,0); | 591 return b_expr(e2,!cond,l1,0); |
589 return; | |
590 case GT: case GE: case LT: case LE: | 592 case GT: case GE: case LT: case LE: |
591 case EQ: case NEQ: | 593 case EQ: case NEQ: |
592 rexpr(e1,l1,cond,INT); | 594 return rexpr(e1,l1,cond,INT); |
593 return; | 595 return l1; |
594 case UGT: case UGE: case ULT: case ULE: | 596 case UGT: case UGE: case ULT: case ULE: |
595 rexpr(e1,l1,cond,UNSIGNED); | 597 return rexpr(e1,l1,cond,UNSIGNED); |
596 return; | |
597 #if FLOAT_CODE | 598 #if FLOAT_CODE |
598 case DOP+GT: | 599 case DOP+GT: |
599 case DOP+GE: | 600 case DOP+GE: |
600 case DOP+EQ: | 601 case DOP+EQ: |
601 case DOP+NEQ: | 602 case DOP+NEQ: |
602 case FOP+GT: | 603 case FOP+GT: |
603 case FOP+GE: | 604 case FOP+GE: |
604 case FOP+EQ: | 605 case FOP+EQ: |
605 case FOP+NEQ: | 606 case FOP+NEQ: |
606 drexpr(cadr(e1),caddr(e1),l1,car(e1),cond); | 607 return drexpr(cadr(e1),caddr(e1),l1,car(e1),cond); |
607 return; | |
608 case FOP+LT: | 608 case FOP+LT: |
609 case FOP+LE: | 609 case FOP+LE: |
610 case DOP+LT: | 610 case DOP+LT: |
611 case DOP+LE: | 611 case DOP+LE: |
612 drexpr(caddr(e1),cadr(e1),l1,rop_dual(car(e1)),cond); | 612 return drexpr(caddr(e1),cadr(e1),l1,rop_dual(car(e1)),cond); |
613 return; | |
614 #endif | 613 #endif |
615 #if LONGLONG_CODE | 614 #if LONGLONG_CODE |
616 case LOP+GT: | 615 case LOP+GT: |
617 case LOP+GE: | 616 case LOP+GE: |
618 case LOP+EQ: | 617 case LOP+EQ: |
619 case LOP+NEQ: | 618 case LOP+NEQ: |
620 case LOP+UGT: | 619 case LOP+UGT: |
621 case LOP+UGE: | 620 case LOP+UGE: |
622 lrexpr(cadr(e1),caddr(e1),l1,car(e1),cond); | 621 return lrexpr(cadr(e1),caddr(e1),l1,car(e1),cond); |
623 return; | |
624 case LOP+LT: | 622 case LOP+LT: |
625 case LOP+LE: | 623 case LOP+LE: |
626 case LOP+ULT: | 624 case LOP+ULT: |
627 case LOP+ULE: | 625 case LOP+ULE: |
628 lrexpr(caddr(e1),cadr(e1),l1,rop_dual(car(e1)),cond); | 626 return lrexpr(caddr(e1),cadr(e1),l1,rop_dual(car(e1)),cond); |
629 return; | |
630 #endif | 627 #endif |
631 case LAND: | 628 case LAND: |
632 bexpr(e2,0,cond?(l2=fwdlabel()):l1); | 629 l2=bexpr(e2,0,cond?(l2=fwdlabel()):l1); |
633 bexpr_u(caddr(e1),cond,l1); | 630 l1=bexpr_u(caddr(e1),cond,l1); |
634 if(cond) fwddef(l2); | 631 if(cond) fwddef(l2); |
635 return; | 632 return l1; |
636 case LOR: | 633 case LOR: |
637 bexpr(e2,1,cond?l1:(l2=fwdlabel())); | 634 l2=bexpr(e2,1,cond?l1:(l2=fwdlabel())); |
638 bexpr_u(caddr(e1),cond,l1); | 635 l1=bexpr_u(caddr(e1),cond,l1); |
639 if(!cond) fwddef(l2); | 636 if(!cond) fwddef(l2); |
640 return; | 637 return l1; |
641 case CRGVAR: case CURGVAR: | 638 case CRGVAR: case CURGVAR: |
642 code_cmp_crgvar(e1,USE_CREG,1,l1,cond); | 639 code_cmp_crgvar(e1,USE_CREG,1,l1,cond); |
643 return; | 640 return l1; |
644 case SRGVAR: case SURGVAR: | 641 case SRGVAR: case SURGVAR: |
645 code_cmp_crgvar(e1,USE_CREG,size_of_short,l1,cond); | 642 code_cmp_crgvar(e1,USE_CREG,size_of_short,l1,cond); |
646 return; | 643 return l1; |
647 case CRLVAR: case CURLVAR: | 644 case CRLVAR: case CURLVAR: |
648 code_cmp_crlvar(e2,USE_CREG,1,l1,cond); | 645 code_cmp_crlvar(e2,USE_CREG,1,l1,cond); |
649 return; | 646 return l1; |
650 case SRLVAR: case SURLVAR: | 647 case SRLVAR: case SURLVAR: |
651 code_cmp_crlvar(e2,USE_CREG,size_of_short,l1,cond); | 648 code_cmp_crlvar(e2,USE_CREG,size_of_short,l1,cond); |
652 return; | 649 return l1; |
653 case RGVAR: | 650 case RGVAR: |
654 code_cmp_rgvar(e1,USE_CREG,l1,cond); | 651 code_cmp_rgvar(e1,USE_CREG,l1,cond); |
655 return; | 652 return l1; |
656 case RLVAR: | 653 case RLVAR: |
657 code_cmp_rlvar(e2,USE_CREG,l1,cond); | 654 code_cmp_rlvar(e2,USE_CREG,l1,cond); |
658 return; | 655 return l1; |
659 #if FLOATC_DOE | 656 #if FLOATC_DOE |
660 case DRLVAR: | 657 case DRLVAR: |
661 code_cmp_drlvar(e2,USE_CREG,1,l1,cond); | 658 code_cmp_drlvar(e2,USE_CREG,1,l1,cond); |
662 return; | 659 return l1; |
663 case FRLVAR: | 660 case FRLVAR: |
664 code_cmp_drlvar(e2,USE_CREG,0,l1,cond); | 661 code_cmp_drlvar(e2,USE_CREG,0,l1,cond); |
665 return; | 662 return l1; |
666 case DRGVAR: | 663 case DRGVAR: |
667 code_cmp_drgvar(e2,USE_CREG,1,l1,cond); | 664 code_cmp_drgvar(e2,USE_CREG,1,l1,cond); |
668 return; | 665 return l1; |
669 case FRGVAR: | 666 case FRGVAR: |
670 code_cmp_drgvar(e2,USE_CREG,0,l1,cond); | 667 code_cmp_drgvar(e2,USE_CREG,0,l1,cond); |
671 return; | 668 return l1; |
672 case FREGISTER: | 669 case FREGISTER: |
673 code_cmp_dregister(e2,0,l1,cond); | 670 code_cmp_dregister(e2,0,l1,cond); |
674 return; | 671 return l1; |
675 case DREGISTER: | 672 case DREGISTER: |
676 code_cmp_dregister(e2,1,l1,cond); | 673 code_cmp_dregister(e2,1,l1,cond); |
677 return; | 674 return l1; |
678 case DCONST: | 675 case DCONST: |
679 case FCONST: | 676 case FCONST: |
680 if(control&&((dcadr(e2)!=0.0)^cond)) jmp(l1); | 677 if(control&&((dcadr(e2)!=0.0)^cond)) { |
681 return; | 678 gen_jmp(l1); return l1; |
679 else return 0; | |
682 #endif | 680 #endif |
683 #if LONGLONG_DOE | 681 #if LONGLONG_DOE |
684 case LRLVAR: | 682 case LRLVAR: |
685 code_cmp_lrlvar(e2,1,l1,cond); | 683 code_cmp_lrlvar(e2,1,l1,cond); |
686 return; | 684 return l1; |
687 case LRGVAR: | 685 case LRGVAR: |
688 code_cmp_lrgvar(e2,1,l1,cond); | 686 code_cmp_lrgvar(e2,1,l1,cond); |
689 return; | 687 return l1; |
690 case LREGISTER: | 688 case LREGISTER: |
691 code_cmp_lregister(e2,1,l1,cond); | 689 code_cmp_lregister(e2,1,l1,cond); |
692 return; | 690 return l1; |
693 case LCONST: | 691 case LCONST: |
694 if(control&&((lcadr(e2)!=0)^cond)) jmp(l1); | 692 if(control&&((lcadr(e2)!=0)^cond)) { |
695 return; | 693 gen_jmp(l1); return l1; |
694 else return 0; | |
696 #endif | 695 #endif |
697 case REGISTER: | 696 case REGISTER: |
698 code_cmp_register(e2,l1,cond); | 697 code_cmp_register(e2,l1,cond); |
699 return; | 698 return l1; |
700 case CONST: | 699 case CONST: |
701 if(control&&((cond&&e2)||(!cond&&!e2))) jmp(l1); | 700 if(control&&((cond&&e2)||(!cond&&!e2))) { |
702 return; | 701 gen_jmp(l1); return l1; |
702 } else return 0; | |
703 default: | 703 default: |
704 if(err) { | 704 if(err) { |
705 error(-1); return; /* recursive g_expr/b_expr */ | 705 error(-1); return l1; /* recursive g_expr/b_expr */ |
706 } | 706 } |
707 t=g_expr(e1); | 707 t=g_expr(e1); |
708 if (!use) return; | 708 if (!use) return l1; |
709 if (0) ; | 709 if (0) ; |
710 #if FLOAT_CODE | 710 #if FLOAT_CODE |
711 else if(t==FLOAT) | 711 else if(t==FLOAT) |
712 code_cmp_dregister(USE_CREG,0,l1,cond); | 712 code_cmp_dregister(USE_CREG,0,l1,cond); |
713 else if(t==DOUBLE) | 713 else if(t==DOUBLE) |
717 else if(t==LONGLONG||t==ULONGLONG) | 717 else if(t==LONGLONG||t==ULONGLONG) |
718 code_cmp_lregister(USE_CREG,l1,cond); | 718 code_cmp_lregister(USE_CREG,l1,cond); |
719 #endif | 719 #endif |
720 else | 720 else |
721 code_cmp_register(USE_CREG,l1,cond); | 721 code_cmp_register(USE_CREG,l1,cond); |
722 return; | 722 return l1; |
723 } | 723 } |
724 } | 724 } |
725 | 725 |
726 extern int | 726 extern int |
727 is_code(NMTBL *fnptr) | 727 is_code(NMTBL *fnptr) |
2212 fwdlabel(void) | 2212 fwdlabel(void) |
2213 { | 2213 { |
2214 return labelno++; | 2214 return labelno++; |
2215 } | 2215 } |
2216 | 2216 |
2217 static void | |
2218 checkjmp(int l) | |
2219 { | |
2220 if (pending_jmp) { | |
2221 if (pending_jmp!=l) { | |
2222 jmp(pending_jmp); | |
2223 control=0; | |
2224 } | |
2225 pending_jmp=0; | |
2226 } | |
2227 } | |
2228 | |
2217 extern void | 2229 extern void |
2218 fwddef(int l) | 2230 fwddef(int l) |
2219 { | 2231 { |
2232 if (l==0) return; | |
2233 checkjmp(l); | |
2220 control=1; | 2234 control=1; |
2221 if (!chk) | 2235 if (!chk) |
2222 code_label(l); | 2236 code_label(l); |
2223 } | 2237 } |
2224 | 2238 |
2225 extern int | 2239 extern int |
2226 backdef(void) | 2240 backdef(void) |
2227 { | 2241 { |
2242 checkjmp(0); | |
2228 control=1; | 2243 control=1; |
2229 if (!chk) | 2244 if (!chk) |
2230 code_label(labelno); | 2245 code_label(labelno); |
2231 return labelno++; | 2246 return labelno++; |
2232 } | 2247 } |
2234 extern void | 2249 extern void |
2235 def_label(int cslabel, int dlabel) | 2250 def_label(int cslabel, int dlabel) |
2236 { | 2251 { |
2237 int fl; | 2252 int fl; |
2238 | 2253 |
2254 checkjmp(0); | |
2239 fl = 0; | 2255 fl = 0; |
2240 if (control) { | 2256 if (control) { |
2241 jmp(fl=fwdlabel()); | 2257 gen_jmp(fl=fwdlabel()); |
2242 } | 2258 } |
2243 fwddef(cslabel); | 2259 fwddef(cslabel); |
2244 if (dlabel) | 2260 if (dlabel) |
2245 jmp(dlabel); | 2261 gen_jmp(dlabel); |
2246 if (fl) { | 2262 if (fl) { |
2247 fwddef(fl); | 2263 fwddef(fl); |
2248 } | 2264 } |
2249 } | 2265 } |
2250 | 2266 |
2251 extern void | 2267 extern void |
2252 ret(void) | 2268 ret(void) |
2253 { | 2269 { |
2254 code_set_return_register(1); | 2270 code_set_return_register(1); |
2255 jmp(retlabel); | 2271 gen_jmp(retlabel); |
2256 } | 2272 } |
2257 | 2273 |
2258 extern void | 2274 extern void |
2259 opening(char *filename) | 2275 opening(char *filename) |
2260 { | 2276 { |
2892 checkret(void) | 2908 checkret(void) |
2893 { | 2909 { |
2894 if (cslabel==0) { | 2910 if (cslabel==0) { |
2895 if (!control) error(-1); // no execute code in switch | 2911 if (!control) error(-1); // no execute code in switch |
2896 jmp(cslabel=fwdlabel()); | 2912 jmp(cslabel=fwdlabel()); |
2913 control=0; | |
2897 } else if (retpending) { | 2914 } else if (retpending) { |
2898 ret(); | 2915 ret(); |
2899 control=0; | 2916 control=0; |
2900 retpending=0; | 2917 retpending=0; |
2901 } | 2918 } |
2902 if (lastexp) { | 2919 if (lastexp) { |
2920 if(!control) error(-1); | |
2903 gexpr(lastexp,0); | 2921 gexpr(lastexp,0); |
2904 lastexp = 0; | 2922 lastexp = 0; |
2905 } | 2923 } |
2906 } | 2924 } |
2907 | 2925 |
3759 } | 3777 } |
3760 | 3778 |
3761 extern void | 3779 extern void |
3762 gen_jmp(int l) | 3780 gen_jmp(int l) |
3763 { | 3781 { |
3764 jmp(l); | 3782 control=0; |
3783 if (!pending_jmp) { | |
3784 pending_jmp = l; | |
3785 } | |
3765 } | 3786 } |
3766 | 3787 |
3767 extern void | 3788 extern void |
3768 gen_indirect_goto(int e1) | 3789 gen_indirect_goto(int e1) |
3769 { | 3790 { |