OLD | NEW |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #undef EXTERN | 5 #undef EXTERN |
6 #define EXTERN | 6 #define EXTERN |
7 #include <u.h> | 7 #include <u.h> |
8 #include <libc.h> | 8 #include <libc.h> |
9 #include "gg.h" | 9 #include "gg.h" |
10 #include "opt.h" | 10 #include "opt.h" |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 { | 99 { |
100 Prog *p; | 100 Prog *p; |
101 Node reg, con; | 101 Node reg, con; |
102 | 102 |
103 switch(proc) { | 103 switch(proc) { |
104 default: | 104 default: |
105 fatal("ginscall: bad proc %d", proc); | 105 fatal("ginscall: bad proc %d", proc); |
106 break; | 106 break; |
107 | 107 |
108 case 0: // normal call | 108 case 0: // normal call |
| 109 case -1: // normal call but no return |
109 p = gins(ACALL, N, f); | 110 p = gins(ACALL, N, f); |
110 afunclit(&p->to); | 111 afunclit(&p->to); |
| 112 if(proc == -1) |
| 113 gins(AUNDEF, N, N); |
111 break; | 114 break; |
112 | 115 |
113 case 1: // call in new proc (go) | 116 case 1: // call in new proc (go) |
114 case 2: // deferred call (defer) | 117 case 2: // deferred call (defer) |
115 nodreg(®, types[TINT32], D_CX); | 118 nodreg(®, types[TINT32], D_CX); |
116 gins(APUSHL, f, N); | 119 gins(APUSHL, f, N); |
117 nodconst(&con, types[TINT32], argsize(f->type)); | 120 nodconst(&con, types[TINT32], argsize(f->type)); |
118 gins(APUSHL, &con, N); | 121 gins(APUSHL, &con, N); |
119 if(proc == 1) | 122 if(proc == 1) |
120 ginscall(newproc, 0); | 123 ginscall(newproc, 0); |
121 else | 124 else |
122 ginscall(deferproc, 0); | 125 ginscall(deferproc, 0); |
123 gins(APOPL, N, ®); | 126 gins(APOPL, N, ®); |
124 gins(APOPL, N, ®); | 127 gins(APOPL, N, ®); |
125 if(proc == 2) { | 128 if(proc == 2) { |
126 nodreg(®, types[TINT64], D_AX); | 129 nodreg(®, types[TINT64], D_AX); |
127 gins(ATESTL, ®, ®); | 130 gins(ATESTL, ®, ®); |
128 » » » patch(gbranch(AJNE, T), retpc); | 131 » » » patch(gbranch(AJNE, T, -1), retpc); |
129 } | 132 } |
130 break; | 133 break; |
131 } | 134 } |
132 } | 135 } |
133 | 136 |
134 /* | 137 /* |
135 * n is call to interface method. | 138 * n is call to interface method. |
136 * generate res = n. | 139 * generate res = n. |
137 */ | 140 */ |
138 void | 141 void |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
532 if(!samereg(ax, res) && !samereg(dx, res)) | 535 if(!samereg(ax, res) && !samereg(dx, res)) |
533 regalloc(&n1, t, res); | 536 regalloc(&n1, t, res); |
534 else | 537 else |
535 regalloc(&n1, t, N); | 538 regalloc(&n1, t, N); |
536 gmove(&t2, &n1); | 539 gmove(&t2, &n1); |
537 gmove(&t1, ax); | 540 gmove(&t1, ax); |
538 p3 = P; | 541 p3 = P; |
539 if(check) { | 542 if(check) { |
540 nodconst(&n4, t, -1); | 543 nodconst(&n4, t, -1); |
541 gins(optoas(OCMP, t), &n1, &n4); | 544 gins(optoas(OCMP, t), &n1, &n4); |
542 » » p1 = gbranch(optoas(ONE, t), T); | 545 » » p1 = gbranch(optoas(ONE, t), T, +1); |
543 nodconst(&n4, t, -1LL<<(t->width*8-1)); | 546 nodconst(&n4, t, -1LL<<(t->width*8-1)); |
544 gins(optoas(OCMP, t), ax, &n4); | 547 gins(optoas(OCMP, t), ax, &n4); |
545 » » p2 = gbranch(optoas(ONE, t), T); | 548 » » p2 = gbranch(optoas(ONE, t), T, +1); |
546 if(op == ODIV) | 549 if(op == ODIV) |
547 gmove(&n4, res); | 550 gmove(&n4, res); |
548 if(op == OMOD) { | 551 if(op == OMOD) { |
549 nodconst(&n4, t, 0); | 552 nodconst(&n4, t, 0); |
550 gmove(&n4, res); | 553 gmove(&n4, res); |
551 } | 554 } |
552 » » p3 = gbranch(AJMP, T); | 555 » » p3 = gbranch(AJMP, T, 0); |
553 patch(p1, pc); | 556 patch(p1, pc); |
554 patch(p2, pc); | 557 patch(p2, pc); |
555 } | 558 } |
556 if(!issigned[t->etype]) { | 559 if(!issigned[t->etype]) { |
557 nodconst(&nz, t, 0); | 560 nodconst(&nz, t, 0); |
558 gmove(&nz, dx); | 561 gmove(&nz, dx); |
559 } else | 562 } else |
560 gins(optoas(OEXTEND, t), N, N); | 563 gins(optoas(OEXTEND, t), N, N); |
561 gins(optoas(op, t), &n1, N); | 564 gins(optoas(op, t), &n1, N); |
562 regfree(&n1); | 565 regfree(&n1); |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 gmove(&lo, &n1); | 701 gmove(&lo, &n1); |
699 } | 702 } |
700 } else { | 703 } else { |
701 if(nr->type->width > 4) { | 704 if(nr->type->width > 4) { |
702 // delayed reg alloc | 705 // delayed reg alloc |
703 nodreg(&n1, types[TUINT32], D_CX); | 706 nodreg(&n1, types[TUINT32], D_CX); |
704 regalloc(&n1, types[TUINT32], &n1); // to ho
ld the shift type in CX | 707 regalloc(&n1, types[TUINT32], &n1); // to ho
ld the shift type in CX |
705 split64(&nt, &lo, &hi); | 708 split64(&nt, &lo, &hi); |
706 gmove(&lo, &n1); | 709 gmove(&lo, &n1); |
707 gins(optoas(OCMP, types[TUINT32]), &hi, ncon(0)); | 710 gins(optoas(OCMP, types[TUINT32]), &hi, ncon(0)); |
708 » » » p2 = gbranch(optoas(ONE, types[TUINT32]), T); | 711 » » » p2 = gbranch(optoas(ONE, types[TUINT32]), T, +1); |
709 gins(optoas(OCMP, types[TUINT32]), &n1, ncon(w)); | 712 gins(optoas(OCMP, types[TUINT32]), &n1, ncon(w)); |
710 » » » p1 = gbranch(optoas(OLT, types[TUINT32]), T); | 713 » » » p1 = gbranch(optoas(OLT, types[TUINT32]), T, +1); |
711 patch(p2, pc); | 714 patch(p2, pc); |
712 } else { | 715 } else { |
713 gins(optoas(OCMP, nr->type), &n1, ncon(w)); | 716 gins(optoas(OCMP, nr->type), &n1, ncon(w)); |
714 » » » p1 = gbranch(optoas(OLT, types[TUINT32]), T); | 717 » » » p1 = gbranch(optoas(OLT, types[TUINT32]), T, +1); |
715 } | 718 } |
716 if(op == ORSH && issigned[nl->type->etype]) { | 719 if(op == ORSH && issigned[nl->type->etype]) { |
717 gins(a, ncon(w-1), &n2); | 720 gins(a, ncon(w-1), &n2); |
718 } else { | 721 } else { |
719 gmove(ncon(0), &n2); | 722 gmove(ncon(0), &n2); |
720 } | 723 } |
721 patch(p1, pc); | 724 patch(p1, pc); |
722 } | 725 } |
723 gins(a, &n1, &n2); | 726 gins(a, &n1, &n2); |
724 | 727 |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
888 nl = &n1; | 891 nl = &n1; |
889 } else if(nr->type->width != t->width) { | 892 } else if(nr->type->width != t->width) { |
890 regalloc(&n1, t, nr); | 893 regalloc(&n1, t, nr); |
891 gmove(nr, &n1); | 894 gmove(nr, &n1); |
892 nr = &n1; | 895 nr = &n1; |
893 } | 896 } |
894 gins(optoas(OCMP, t), nl, nr); | 897 gins(optoas(OCMP, t), nl, nr); |
895 if(n1.op != OXXX) | 898 if(n1.op != OXXX) |
896 regfree(&n1); | 899 regfree(&n1); |
897 if(throwpc == nil) { | 900 if(throwpc == nil) { |
898 » » p1 = gbranch(optoas(op, t), T); | 901 » » p1 = gbranch(optoas(op, t), T, +1); |
899 » » expecttaken(p1, 1); | |
900 throwpc = pc; | 902 throwpc = pc; |
901 » » ginscall(panicslice, 0); | 903 » » ginscall(panicslice, -1); |
902 patch(p1, pc); | 904 patch(p1, pc); |
903 } else { | 905 } else { |
904 op = brcom(op); | 906 op = brcom(op); |
905 » » p1 = gbranch(optoas(op, t), T); | 907 » » p1 = gbranch(optoas(op, t), T, -1); |
906 » » expecttaken(p1, 0); | |
907 patch(p1, throwpc); | 908 patch(p1, throwpc); |
908 } | 909 } |
909 } | 910 } |
910 | 911 |
911 int | 912 int |
912 sleasy(Node *n) | 913 sleasy(Node *n) |
913 { | 914 { |
914 if(n->op != ONAME) | 915 if(n->op != ONAME) |
915 return 0; | 916 return 0; |
916 if(!n->addable) | 917 if(!n->addable) |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1170 } | 1171 } |
1171 | 1172 |
1172 if(!sleasy(res)) { | 1173 if(!sleasy(res)) { |
1173 cgen(&nres, res); | 1174 cgen(&nres, res); |
1174 } | 1175 } |
1175 return 1; | 1176 return 1; |
1176 | 1177 |
1177 no: | 1178 no: |
1178 return 0; | 1179 return 0; |
1179 } | 1180 } |
OLD | NEW |