Left: | ||
Right: |
LEFT | RIGHT |
---|---|
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 // TODO(rsc): | 5 // TODO(rsc): |
6 // assume CLD? | 6 // assume CLD? |
7 | 7 |
8 #include <u.h> | 8 #include <u.h> |
9 #include <libc.h> | 9 #include <libc.h> |
10 #include "gg.h" | 10 #include "gg.h" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
42 * generate: | 42 * generate: |
43 * res = n; | 43 * res = n; |
44 * simplifies and calls gmove. | 44 * simplifies and calls gmove. |
45 * | 45 * |
46 * TODO: | 46 * TODO: |
47 * sudoaddable | 47 * sudoaddable |
48 */ | 48 */ |
49 void | 49 void |
50 cgen(Node *n, Node *res) | 50 cgen(Node *n, Node *res) |
51 { | 51 { |
52 » Node *nl, *nr, *r, n1, n2, nt; // , f0, f1; | 52 » Node *nl, *nr, *r, n1, n2, nt; |
bradfitz
2012/10/07 19:39:33
remove comment?
| |
53 Prog *p1, *p2, *p3; | 53 Prog *p1, *p2, *p3; |
54 int a; | 54 int a; |
55 | 55 |
56 if(debug['g']) { | 56 if(debug['g']) { |
57 dump("\ncgen-n", n); | 57 dump("\ncgen-n", n); |
58 dump("cgen-res", res); | 58 dump("cgen-res", res); |
59 } | 59 } |
60 | 60 |
61 if(n == N || n->type == T) | 61 if(n == N || n->type == T) |
62 fatal("cgen: n nil"); | 62 fatal("cgen: n nil"); |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
419 regfree(&n1); | 419 regfree(&n1); |
420 } | 420 } |
421 return; | 421 return; |
422 | 422 |
423 uop: // unary | 423 uop: // unary |
424 tempname(&n1, nl->type); | 424 tempname(&n1, nl->type); |
425 cgen(nl, &n1); | 425 cgen(nl, &n1); |
426 gins(a, N, &n1); | 426 gins(a, N, &n1); |
427 gmove(&n1, res); | 427 gmove(&n1, res); |
428 return; | 428 return; |
429 | |
430 /* | |
bradfitz
2012/10/07 19:39:33
temporary?
| |
431 flt: // floating-point. 387 (not SSE2) to interoperate with 8c | |
432 nodreg(&f0, nl->type, D_F0); | |
433 nodreg(&f1, n->type, D_F0+1); | |
434 if(nr != N) | |
435 goto flt2; | |
436 | |
437 // unary | |
438 cgen(nl, &f0); | |
439 if(n->op != OCONV && n->op != OPLUS) | |
440 gins(foptoas(n->op, n->type, 0), N, N); | |
441 gmove(&f0, res); | |
442 return; | |
443 | |
444 flt2: // binary | |
445 if(nl->ullman >= nr->ullman) { | |
446 cgen(nl, &f0); | |
447 if(nr->addable) | |
448 gins(foptoas(n->op, n->type, 0), nr, &f0); | |
449 else { | |
450 cgen(nr, &f0); | |
451 gins(foptoas(n->op, n->type, Fpop), &f0, &f1); | |
452 } | |
453 } else { | |
454 cgen(nr, &f0); | |
455 if(nl->addable) | |
456 gins(foptoas(n->op, n->type, Frev), nl, &f0); | |
457 else { | |
458 cgen(nl, &f0); | |
459 gins(foptoas(n->op, n->type, Frev|Fpop), &f0, &f1); | |
460 } | |
461 } | |
462 gmove(&f0, res); | |
463 return; | |
464 */ | |
465 } | 429 } |
466 | 430 |
467 /* | 431 /* |
468 * generate an addressable node in res, containing the value of n. | 432 * generate an addressable node in res, containing the value of n. |
469 * n is an array index, and might be any size; res width is <= 32-bit. | 433 * n is an array index, and might be any size; res width is <= 32-bit. |
470 * returns Prog* to patch to panic call. | 434 * returns Prog* to patch to panic call. |
471 */ | 435 */ |
472 Prog* | 436 Prog* |
473 igenindex(Node *n, Node *res) | 437 igenindex(Node *n, Node *res) |
474 { | 438 { |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
804 * on exit, a has been changed to be *newreg. | 768 * on exit, a has been changed to be *newreg. |
805 * caller must regfree(a). | 769 * caller must regfree(a). |
806 */ | 770 */ |
807 void | 771 void |
808 igen(Node *n, Node *a, Node *res) | 772 igen(Node *n, Node *a, Node *res) |
809 { | 773 { |
810 Type *fp; | 774 Type *fp; |
811 Iter flist; | 775 Iter flist; |
812 Node n1; | 776 Node n1; |
813 | 777 |
778 if(debug['g']) { | |
779 dump("\nigen-n", n); | |
780 } | |
814 switch(n->op) { | 781 switch(n->op) { |
815 case ONAME: | 782 case ONAME: |
816 if((n->class&PHEAP) || n->class == PPARAMREF) | 783 if((n->class&PHEAP) || n->class == PPARAMREF) |
817 break; | 784 break; |
818 *a = *n; | 785 *a = *n; |
819 return; | 786 return; |
820 | 787 |
821 case OINDREG: | 788 case OINDREG: |
822 // Increase the refcount of the register so that igen's caller | 789 // Increase the refcount of the register so that igen's caller |
823 // has to call regfree. | 790 // has to call regfree. |
824 if(n->val.u.reg != D_SP) | 791 if(n->val.u.reg != D_SP) |
825 reg[n->val.u.reg]++; | 792 reg[n->val.u.reg]++; |
826 *a = *n; | 793 *a = *n; |
827 return; | 794 return; |
828 | 795 |
829 case ODOT: | 796 case ODOT: |
830 igen(n->left, a, res); | 797 igen(n->left, a, res); |
831 a->xoffset += n->xoffset; | 798 a->xoffset += n->xoffset; |
832 a->type = n->type; | 799 a->type = n->type; |
833 return; | 800 return; |
834 | 801 |
835 case ODOTPTR: | 802 case ODOTPTR: |
836 » » regalloc(a, types[tptr], res); | 803 » » if(n->left->addable |
837 » » cgen(n->left, a); | 804 » » » || n->left->op == OCALLFUNC |
805 » » » || n->left->op == OCALLMETH | |
806 » » » || n->left->op == OCALLINTER) { | |
807 » » » // igen-able nodes. | |
808 » » » igen(n->left, &n1, res); | |
809 » » » regalloc(a, types[tptr], &n1); | |
810 » » » gmove(&n1, a); | |
811 » » » regfree(&n1); | |
812 » » } else { | |
813 » » » regalloc(a, types[tptr], res); | |
814 » » » cgen(n->left, a); | |
815 » » } | |
838 if(n->xoffset != 0) { | 816 if(n->xoffset != 0) { |
839 // explicit check for nil if struct is large enough | 817 // explicit check for nil if struct is large enough |
840 // that we might derive too big a pointer. | 818 // that we might derive too big a pointer. |
841 if(n->left->type->type->width >= unmappedzero) { | 819 if(n->left->type->type->width >= unmappedzero) { |
842 n1 = *a; | 820 n1 = *a; |
843 n1.op = OINDREG; | 821 n1.op = OINDREG; |
844 n1.type = types[TUINT8]; | 822 n1.type = types[TUINT8]; |
845 n1.xoffset = 0; | 823 n1.xoffset = 0; |
846 gins(ATESTB, nodintconst(0), &n1); | 824 gins(ATESTB, nodintconst(0), &n1); |
847 } | 825 } |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1241 fatal("sgen copy %lld", w); | 1219 fatal("sgen copy %lld", w); |
1242 | 1220 |
1243 if(w == 0) { | 1221 if(w == 0) { |
1244 // evaluate side effects only. | 1222 // evaluate side effects only. |
1245 tempname(&tdst, types[tptr]); | 1223 tempname(&tdst, types[tptr]); |
1246 agen(res, &tdst); | 1224 agen(res, &tdst); |
1247 agen(n, &tdst); | 1225 agen(n, &tdst); |
1248 return; | 1226 return; |
1249 } | 1227 } |
1250 | 1228 |
1251 » if (w == 8 || w == 12) { | 1229 » // Avoid taking the address for simple enough types. |
1252 » » if(componentgen(n, res)) | 1230 » if(componentgen(n, res)) |
1253 » » » return; | 1231 » » return; |
1254 » } | |
1255 | 1232 |
1256 // offset on the stack | 1233 // offset on the stack |
1257 osrc = stkof(n); | 1234 osrc = stkof(n); |
1258 odst = stkof(res); | 1235 odst = stkof(res); |
1259 ········ | 1236 ········ |
1260 if(osrc != -1000 && odst != -1000 && (osrc == 1000 || odst == 1000)) { | 1237 if(osrc != -1000 && odst != -1000 && (osrc == 1000 || odst == 1000)) { |
1261 // osrc and odst both on stack, and at least one is in | 1238 // osrc and odst both on stack, and at least one is in |
1262 // an unknown position. Could generate code to test | 1239 // an unknown position. Could generate code to test |
1263 // for forward/backward copy, but instead just copy | 1240 // for forward/backward copy, but instead just copy |
1264 // to a temporary location first. | 1241 // to a temporary location first. |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1346 } | 1323 } |
1347 | 1324 |
1348 switch(n->op) { | 1325 switch(n->op) { |
1349 case ONAME: | 1326 case ONAME: |
1350 return 1; | 1327 return 1; |
1351 } | 1328 } |
1352 return 0; | 1329 return 0; |
1353 } | 1330 } |
1354 | 1331 |
1355 /* | 1332 /* |
1356 * copy a structure component by component | 1333 * copy a composite value by moving its individual components. |
1334 * Slices, strings and interfaces are supported. | |
1335 * nr is N when assigning a zero value. | |
1357 * return 1 if can do, 0 if cant. | 1336 * return 1 if can do, 0 if cant. |
1358 * nr is N for copy zero | |
1359 */ | 1337 */ |
1360 int | 1338 int |
1361 componentgen(Node *nr, Node *nl) | 1339 componentgen(Node *nr, Node *nl) |
1362 { | 1340 { |
1363 Node nodl, nodr; | 1341 Node nodl, nodr; |
1364 int freel, freer; | 1342 int freel, freer; |
1365 | 1343 |
1366 freel = 0; | 1344 freel = 0; |
1367 freer = 0; | 1345 freer = 0; |
1368 | 1346 |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1482 regfree(&nodl); | 1460 regfree(&nodl); |
1483 return 0; | 1461 return 0; |
1484 | 1462 |
1485 yes: | 1463 yes: |
1486 if(freer) | 1464 if(freer) |
1487 regfree(&nodr); | 1465 regfree(&nodr); |
1488 if(freel) | 1466 if(freel) |
1489 regfree(&nodl); | 1467 regfree(&nodl); |
1490 return 1; | 1468 return 1; |
1491 } | 1469 } |
LEFT | RIGHT |