LEFT | RIGHT |
(no file at all) | |
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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 { | 59 { |
60 Prog *p; | 60 Prog *p; |
61 Node reg, con; | 61 Node reg, con; |
62 | 62 |
63 switch(proc) { | 63 switch(proc) { |
64 default: | 64 default: |
65 fatal("ginscall: bad proc %d", proc); | 65 fatal("ginscall: bad proc %d", proc); |
66 break; | 66 break; |
67 | 67 |
68 case 0: // normal call | 68 case 0: // normal call |
| 69 case -1: // normal call but no return |
69 p = gins(ACALL, N, f); | 70 p = gins(ACALL, N, f); |
70 afunclit(&p->to); | 71 afunclit(&p->to); |
| 72 if(proc == -1) |
| 73 gins(AUNDEF, N, N); |
71 break; | 74 break; |
72 | 75 |
73 case 1: // call in new proc (go) | 76 case 1: // call in new proc (go) |
74 case 2: // deferred call (defer) | 77 case 2: // deferred call (defer) |
75 nodreg(®, types[TINT64], D_CX); | 78 nodreg(®, types[TINT64], D_CX); |
76 gins(APUSHQ, f, N); | 79 gins(APUSHQ, f, N); |
77 nodconst(&con, types[TINT32], argsize(f->type)); | 80 nodconst(&con, types[TINT32], argsize(f->type)); |
78 gins(APUSHQ, &con, N); | 81 gins(APUSHQ, &con, N); |
79 if(proc == 1) | 82 if(proc == 1) |
80 ginscall(newproc, 0); | 83 ginscall(newproc, 0); |
81 else { | 84 else { |
82 if(!hasdefer) | 85 if(!hasdefer) |
83 fatal("hasdefer=0 but has defer"); | 86 fatal("hasdefer=0 but has defer"); |
84 ginscall(deferproc, 0); | 87 ginscall(deferproc, 0); |
85 } | 88 } |
86 gins(APOPQ, N, ®); | 89 gins(APOPQ, N, ®); |
87 gins(APOPQ, N, ®); | 90 gins(APOPQ, N, ®); |
88 if(proc == 2) { | 91 if(proc == 2) { |
89 nodreg(®, types[TINT64], D_AX); | 92 nodreg(®, types[TINT64], D_AX); |
90 gins(ATESTQ, ®, ®); | 93 gins(ATESTQ, ®, ®); |
91 » » » patch(gbranch(AJNE, T), retpc); | 94 » » » patch(gbranch(AJNE, T, -1), retpc); |
92 } | 95 } |
93 break; | 96 break; |
94 } | 97 } |
95 } | 98 } |
96 | 99 |
97 /* | 100 /* |
98 * n is call to interface method. | 101 * n is call to interface method. |
99 * generate res = n. | 102 * generate res = n. |
100 */ | 103 */ |
101 void | 104 void |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
500 ax.type = t; | 503 ax.type = t; |
501 n3.type = t; | 504 n3.type = t; |
502 gmove(&ax1, &ax); | 505 gmove(&ax1, &ax); |
503 gmove(&n31, &n3); | 506 gmove(&n31, &n3); |
504 } | 507 } |
505 | 508 |
506 p3 = P; | 509 p3 = P; |
507 if(check) { | 510 if(check) { |
508 nodconst(&n4, t, -1); | 511 nodconst(&n4, t, -1); |
509 gins(optoas(OCMP, t), &n3, &n4); | 512 gins(optoas(OCMP, t), &n3, &n4); |
510 » » p1 = gbranch(optoas(ONE, t), T); | 513 » » p1 = gbranch(optoas(ONE, t), T, +1); |
511 » » expecttaken(p1, 1); | |
512 nodconst(&n4, t, -1LL<<(t->width*8-1)); | 514 nodconst(&n4, t, -1LL<<(t->width*8-1)); |
513 if(t->width == 8) { | 515 if(t->width == 8) { |
514 n5 = n4; | 516 n5 = n4; |
515 regalloc(&n4, t, N); | 517 regalloc(&n4, t, N); |
516 gins(AMOVQ, &n5, &n4); | 518 gins(AMOVQ, &n5, &n4); |
517 } | 519 } |
518 gins(optoas(OCMP, t), &ax, &n4); | 520 gins(optoas(OCMP, t), &ax, &n4); |
519 » » p2 = gbranch(optoas(ONE, t), T); | 521 » » p2 = gbranch(optoas(ONE, t), T, +1); |
520 » » expecttaken(p2, 1); | |
521 if(op == ODIV) | 522 if(op == ODIV) |
522 gmove(&n4, res); | 523 gmove(&n4, res); |
523 if(t->width == 8) | 524 if(t->width == 8) |
524 regfree(&n4); | 525 regfree(&n4); |
525 if(op == OMOD) { | 526 if(op == OMOD) { |
526 nodconst(&n4, t, 0); | 527 nodconst(&n4, t, 0); |
527 gmove(&n4, res); | 528 gmove(&n4, res); |
528 } | 529 } |
529 » » p3 = gbranch(AJMP, T); | 530 » » p3 = gbranch(AJMP, T, 0); |
530 patch(p1, pc); | 531 patch(p1, pc); |
531 patch(p2, pc); | 532 patch(p2, pc); |
532 } | 533 } |
533 savex(D_DX, &dx, &olddx, res, t); | 534 savex(D_DX, &dx, &olddx, res, t); |
534 if(!issigned[t->etype]) { | 535 if(!issigned[t->etype]) { |
535 nodconst(&n4, t, 0); | 536 nodconst(&n4, t, 0); |
536 gmove(&n4, &dx); | 537 gmove(&n4, &dx); |
537 } else | 538 } else |
538 gins(optoas(OEXTEND, t), N, N); | 539 gins(optoas(OEXTEND, t), N, N); |
539 gins(a, &n3, N); | 540 gins(a, &n3, N); |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
937 cgen(nr, &n1); | 938 cgen(nr, &n1); |
938 gmove(&n1, &n3); | 939 gmove(&n1, &n3); |
939 cgen(nl, &n2); | 940 cgen(nl, &n2); |
940 } | 941 } |
941 regfree(&n3); | 942 regfree(&n3); |
942 | 943 |
943 // test and fix up large shifts | 944 // test and fix up large shifts |
944 if(!bounded) { | 945 if(!bounded) { |
945 nodconst(&n3, tcount, nl->type->width*8); | 946 nodconst(&n3, tcount, nl->type->width*8); |
946 gins(optoas(OCMP, tcount), &n1, &n3); | 947 gins(optoas(OCMP, tcount), &n1, &n3); |
947 » » p1 = gbranch(optoas(OLT, tcount), T); | 948 » » p1 = gbranch(optoas(OLT, tcount), T, +1); |
948 » » expecttaken(p1, 1); | |
949 if(op == ORSH && issigned[nl->type->etype]) { | 949 if(op == ORSH && issigned[nl->type->etype]) { |
950 nodconst(&n3, types[TUINT32], nl->type->width*8-1); | 950 nodconst(&n3, types[TUINT32], nl->type->width*8-1); |
951 gins(a, &n3, &n2); | 951 gins(a, &n3, &n2); |
952 } else { | 952 } else { |
953 nodconst(&n3, nl->type, 0); | 953 nodconst(&n3, nl->type, 0); |
954 gmove(&n3, &n2); | 954 gmove(&n3, &n2); |
955 } | 955 } |
956 patch(p1, pc); | 956 patch(p1, pc); |
957 } | 957 } |
958 | 958 |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1153 } else if(nr->type->width != t->width && nr->op != OLITERAL) { | 1153 } else if(nr->type->width != t->width && nr->op != OLITERAL) { |
1154 regalloc(&n1, t, nr); | 1154 regalloc(&n1, t, nr); |
1155 gmove(nr, &n1); | 1155 gmove(nr, &n1); |
1156 nr = &n1; | 1156 nr = &n1; |
1157 } | 1157 } |
1158 } | 1158 } |
1159 gins(optoas(OCMP, t), nl, nr); | 1159 gins(optoas(OCMP, t), nl, nr); |
1160 if(n1.op != OXXX) | 1160 if(n1.op != OXXX) |
1161 regfree(&n1); | 1161 regfree(&n1); |
1162 if(throwpc == nil) { | 1162 if(throwpc == nil) { |
1163 » » p1 = gbranch(optoas(op, t), T); | 1163 » » p1 = gbranch(optoas(op, t), T, +1); |
1164 » » expecttaken(p1, 1); | |
1165 throwpc = pc; | 1164 throwpc = pc; |
1166 » » ginscall(panicslice, 0); | 1165 » » ginscall(panicslice, -1); |
1167 patch(p1, pc); | 1166 patch(p1, pc); |
1168 } else { | 1167 } else { |
1169 op = brcom(op); | 1168 op = brcom(op); |
1170 » » p1 = gbranch(optoas(op, t), T); | 1169 » » p1 = gbranch(optoas(op, t), T, -1); |
1171 » » expecttaken(p1, 0); | |
1172 patch(p1, throwpc); | 1170 patch(p1, throwpc); |
1173 } | 1171 } |
1174 } | 1172 } |
1175 | 1173 |
1176 int | 1174 int |
1177 sleasy(Node *n) | 1175 sleasy(Node *n) |
1178 { | 1176 { |
1179 if(n->op != ONAME) | 1177 if(n->op != ONAME) |
1180 return 0; | 1178 return 0; |
1181 if(!n->addable) | 1179 if(!n->addable) |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1426 } | 1424 } |
1427 | 1425 |
1428 if(!sleasy(res)) { | 1426 if(!sleasy(res)) { |
1429 cgen(&nres, res); | 1427 cgen(&nres, res); |
1430 } | 1428 } |
1431 return 1; | 1429 return 1; |
1432 | 1430 |
1433 no: | 1431 no: |
1434 return 0; | 1432 return 0; |
1435 } | 1433 } |
LEFT | RIGHT |