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 #include <u.h> | 5 #include <u.h> |
6 #include <libc.h> | 6 #include <libc.h> |
7 #include "gg.h" | 7 #include "gg.h" |
8 | 8 |
9 /* | 9 /* |
10 * generate: | 10 * generate: |
(...skipping 1327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1338 /* | 1338 /* |
1339 * block copy: | 1339 * block copy: |
1340 * memmove(&ns, &n, w); | 1340 * memmove(&ns, &n, w); |
1341 */ | 1341 */ |
1342 void | 1342 void |
1343 sgen(Node *n, Node *ns, int64 w) | 1343 sgen(Node *n, Node *ns, int64 w) |
1344 { | 1344 { |
1345 Node nodl, nodr, nodsi, noddi, cx, oldcx, tmp; | 1345 Node nodl, nodr, nodsi, noddi, cx, oldcx, tmp; |
1346 vlong c, q, odst, osrc; | 1346 vlong c, q, odst, osrc; |
1347 NodeList *l; | 1347 NodeList *l; |
| 1348 Prog *p; |
1348 | 1349 |
1349 if(debug['g']) { | 1350 if(debug['g']) { |
1350 print("\nsgen w=%lld\n", w); | 1351 print("\nsgen w=%lld\n", w); |
1351 dump("r", n); | 1352 dump("r", n); |
1352 dump("res", ns); | 1353 dump("res", ns); |
1353 } | 1354 } |
1354 | 1355 |
1355 if(n->ullman >= UINF && ns->ullman >= UINF) | 1356 if(n->ullman >= UINF && ns->ullman >= UINF) |
1356 fatal("sgen UINF"); | 1357 fatal("sgen UINF"); |
1357 | 1358 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1440 gconreg(addptr, w-8, D_DI); | 1441 gconreg(addptr, w-8, D_DI); |
1441 } | 1442 } |
1442 gconreg(movptr, q, D_CX); | 1443 gconreg(movptr, q, D_CX); |
1443 gins(AREP, N, N); // repeat | 1444 gins(AREP, N, N); // repeat |
1444 gins(AMOVSQ, N, N); // MOVQ *(SI)-,*(DI)- | 1445 gins(AMOVSQ, N, N); // MOVQ *(SI)-,*(DI)- |
1445 } | 1446 } |
1446 // we leave with the flag clear | 1447 // we leave with the flag clear |
1447 gins(ACLD, N, N); | 1448 gins(ACLD, N, N); |
1448 } else { | 1449 } else { |
1449 // normal direction | 1450 // normal direction |
1450 » » if(q >= 4) { | 1451 » » if(q > 128) { |
1451 gconreg(movptr, q, D_CX); | 1452 gconreg(movptr, q, D_CX); |
1452 gins(AREP, N, N); // repeat | 1453 gins(AREP, N, N); // repeat |
1453 gins(AMOVSQ, N, N); // MOVQ *(SI)+,*(DI)+ | 1454 gins(AMOVSQ, N, N); // MOVQ *(SI)+,*(DI)+ |
| 1455 } else if (q >= 4) { |
| 1456 p = gins(ADUFFCOPY, N, N); |
| 1457 p->to.type = D_ADDR; |
| 1458 p->to.sym = linksym(pkglookup("duffcopy", runtimepkg)); |
| 1459 // 14 = magic constant: see ../../pkg/runtime/asm_amd64.
s |
| 1460 p->to.offset = 14*(128-q); |
1454 } else | 1461 } else |
1455 while(q > 0) { | 1462 while(q > 0) { |
1456 gins(AMOVSQ, N, N); // MOVQ *(SI)+,*(DI)+ | 1463 gins(AMOVSQ, N, N); // MOVQ *(SI)+,*(DI)+ |
1457 q--; | 1464 q--; |
1458 } | 1465 } |
1459 // copy the remaining c bytes | 1466 // copy the remaining c bytes |
1460 if(w < 4 || c <= 1 || (odst < osrc && osrc < odst+w)) { | 1467 if(w < 4 || c <= 1 || (odst < osrc && osrc < odst+w)) { |
1461 while(c > 0) { | 1468 while(c > 0) { |
1462 gins(AMOVSB, N, N); // MOVB *(SI)+,*(DI)+ | 1469 gins(AMOVSB, N, N); // MOVB *(SI)+,*(DI)+ |
1463 c--; | 1470 c--; |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1714 regfree(&nodl); | 1721 regfree(&nodl); |
1715 return 0; | 1722 return 0; |
1716 | 1723 |
1717 yes: | 1724 yes: |
1718 if(freer) | 1725 if(freer) |
1719 regfree(&nodr); | 1726 regfree(&nodr); |
1720 if(freel) | 1727 if(freel) |
1721 regfree(&nodl); | 1728 regfree(&nodl); |
1722 return 1; | 1729 return 1; |
1723 } | 1730 } |
OLD | NEW |