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 "gg.h" | 8 #include "gg.h" |
9 | 9 |
10 void | 10 void |
(...skipping 21 matching lines...) Expand all Loading... |
32 void | 32 void |
33 mfree(Node *n) | 33 mfree(Node *n) |
34 { | 34 { |
35 if(n->op == OREGISTER) | 35 if(n->op == OREGISTER) |
36 regfree(n); | 36 regfree(n); |
37 } | 37 } |
38 | 38 |
39 static void | 39 static void |
40 x87clampexp(Node *f) | 40 x87clampexp(Node *f) |
41 { | 41 { |
42 » Node t; | 42 » static Node *t32, *t64, *fn; |
43 | 43 » Node *t; |
44 » tempname(&t, f->type); | 44 |
45 » gmove(f, &t); | 45 » if(fn != curfn) { |
46 » gmove(&t, f); | 46 » » fn = curfn; |
| 47 » » t32 = t64 = N; |
| 48 » } |
| 49 » t = N; |
| 50 » if(simsimtype(f->type) == TFLOAT32 || simsimtype(f->type) == TFLOAT) { |
| 51 » » if(t32 == N) { |
| 52 » » » t32 = nod(ONAME, N, N); |
| 53 » » » tempname(t32, f->type); |
| 54 » » } |
| 55 » » t = t32; |
| 56 » } else if(simsimtype(f->type) == TFLOAT64) { |
| 57 » » if(t64 == N) { |
| 58 » » » t64 = nod(ONAME, N, N); |
| 59 » » » tempname(t64, f->type); |
| 60 » » } |
| 61 » » t = t64; |
| 62 » } else |
| 63 » » fatal("x87clampexp: bad type %T", f->type); |
| 64 » gmove(f, t); |
| 65 » gmove(t, f); |
47 } | 66 } |
48 | 67 |
49 static void | 68 static void |
50 x87scaledown(Node *op, Node *f0, Node *f1) | 69 x87scaledown(Node *op, Node *f0, Node *f1) |
51 { | 70 { |
52 if(op->op != ODIV && op->op != OMUL) | 71 if(op->op != ODIV && op->op != OMUL) |
53 return; | 72 return; |
54 if(op->type != types[TFLOAT64]) | 73 if(op->type != types[TFLOAT64]) |
55 return; | 74 return; |
56 Sym *s = pkglookup("x87scaledown", runtimepkg); | 75 Sym *s = pkglookup("x87scaledown", runtimepkg); |
57 Node *n = newname(s); | 76 Node *n = newname(s); |
58 n->op = ONAME; | 77 n->op = ONAME; |
59 n->class = PEXTERN; | 78 n->class = PEXTERN; |
60 n->type = types[TFLOAT]; | 79 n->type = types[TFLOAT]; |
61 // fprint(2,"%S\n", s); | |
62 // fprint(2,"%N\n",n); | |
63 gins(AFMOVX, n, f0); | 80 gins(AFMOVX, n, f0); |
64 gins(AFMULDP, f0, f1); | 81 gins(AFMULDP, f0, f1); |
65 return; | 82 return; |
66 } | 83 } |
67 | 84 |
68 static void | 85 static void |
69 x87scaleup(Node *op, Node *f0, Node *f1) | 86 x87scaleup(Node *op, Node *f0, Node *f1) |
70 { | 87 { |
71 if(op->op != ODIV && op->op != OMUL) | 88 if(op->op != ODIV && op->op != OMUL) |
72 return; | 89 return; |
73 if(op->type != types[TFLOAT64]) | 90 if(op->type != types[TFLOAT64]) |
74 return; | 91 return; |
75 Sym *s = pkglookup("x87scaleup", runtimepkg); | 92 Sym *s = pkglookup("x87scaleup", runtimepkg); |
76 Node *n = newname(s); | 93 Node *n = newname(s); |
77 n->op = ONAME; | 94 n->op = ONAME; |
78 n->class = PEXTERN; | 95 n->class = PEXTERN; |
79 n->type = types[TFLOAT]; | 96 n->type = types[TFLOAT]; |
80 // fprint(2,"%S\n", s); | |
81 // fprint(2,"%N\n",n); | |
82 gins(AFMOVX, n, f0); | 97 gins(AFMOVX, n, f0); |
83 gins(AFMULDP, f0, f1); | 98 gins(AFMULDP, f0, f1); |
84 return; | 99 return; |
85 } | 100 } |
86 | 101 |
87 /* | 102 /* |
88 * generate: | 103 * generate: |
89 * res = n; | 104 * res = n; |
90 * simplifies and calls gmove. | 105 * simplifies and calls gmove. |
91 * | 106 * |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 uop: // unary | 451 uop: // unary |
437 tempname(&n1, nl->type); | 452 tempname(&n1, nl->type); |
438 cgen(nl, &n1); | 453 cgen(nl, &n1); |
439 gins(a, N, &n1); | 454 gins(a, N, &n1); |
440 gmove(&n1, res); | 455 gmove(&n1, res); |
441 return; | 456 return; |
442 | 457 |
443 flt: // floating-point. 387 (not SSE2) to interoperate with 8c | 458 flt: // floating-point. 387 (not SSE2) to interoperate with 8c |
444 nodreg(&f0, nl->type, D_F0); | 459 nodreg(&f0, nl->type, D_F0); |
445 nodreg(&f1, n->type, D_F0+1); | 460 nodreg(&f1, n->type, D_F0+1); |
446 int dostore = 1; | |
447 if(nr != N) | 461 if(nr != N) |
448 goto flt2; | 462 goto flt2; |
449 | 463 |
450 // unary | 464 // unary |
451 cgen(nl, &f0); | 465 cgen(nl, &f0); |
452 if(n->op != OCONV && n->op != OPLUS) | 466 if(n->op != OCONV && n->op != OPLUS) |
453 gins(foptoas(n->op, n->type, 0), N, N); | 467 gins(foptoas(n->op, n->type, 0), N, N); |
454 if(dostore)» x87clampexp(&f0); | 468 » x87clampexp(&f0); |
455 gmove(&f0, res); | 469 gmove(&f0, res); |
456 return; | 470 return; |
457 | 471 |
458 flt2: // binary | 472 flt2: // binary |
459 ; | |
460 int doscale=1; | |
461 if(nl->ullman >= nr->ullman) { | 473 if(nl->ullman >= nr->ullman) { |
462 cgen(nl, &f0); | 474 cgen(nl, &f0); |
463 if(doscale)» » x87scaledown(n, &f0, &f1); | 475 » » x87scaledown(n, &f0, &f1); |
464 if(nr->addable) | 476 if(nr->addable) |
465 gins(foptoas(n->op, n->type, 0), nr, &f0); | 477 gins(foptoas(n->op, n->type, 0), nr, &f0); |
466 else { | 478 else { |
467 cgen(nr, &f0); | 479 cgen(nr, &f0); |
468 gins(foptoas(n->op, n->type, Fpop), &f0, &f1); | 480 gins(foptoas(n->op, n->type, Fpop), &f0, &f1); |
469 } | 481 } |
470 if(doscale)» » x87scaleup(n, &f0, &f1); | 482 » » x87scaleup(n, &f0, &f1); |
471 } else { | 483 } else { |
472 cgen(nr, &f0); | 484 cgen(nr, &f0); |
473 if(nl->addable) { | 485 if(nl->addable) { |
474 if(doscale){ | |
475 if(n->op == ODIV) | 486 if(n->op == ODIV) |
476 x87scaleup(n, &f0, &f1); | 487 x87scaleup(n, &f0, &f1); |
477 else | 488 else |
478 x87scaledown(n, &f0, &f1); | 489 x87scaledown(n, &f0, &f1); |
479 } | |
480 gins(foptoas(n->op, n->type, Frev), nl, &f0); | 490 gins(foptoas(n->op, n->type, Frev), nl, &f0); |
481 } else { | 491 } else { |
482 cgen(nl, &f0); | 492 cgen(nl, &f0); |
483 if(doscale)» » » x87scaledown(n, &f0, &f1); | 493 » » » x87scaledown(n, &f0, &f1); |
484 gins(foptoas(n->op, n->type, Frev|Fpop), &f0, &f1); | 494 gins(foptoas(n->op, n->type, Frev|Fpop), &f0, &f1); |
485 } | 495 } |
486 if(doscale)» » x87scaleup(n, &f0, &f1); | 496 » » x87scaleup(n, &f0, &f1); |
487 » } | 497 » } |
488 if(dostore)» x87clampexp(&f0); | 498 » x87clampexp(&f0); |
489 gmove(&f0, res); | 499 gmove(&f0, res); |
490 return; | 500 return; |
491 } | 501 } |
492 | 502 |
493 /* | 503 /* |
494 * generate array index into res. | 504 * generate array index into res. |
495 * n might be any size; res is 32-bit. | 505 * n might be any size; res is 32-bit. |
496 * returns Prog* to patch to panic call. | 506 * returns Prog* to patch to panic call. |
497 */ | 507 */ |
498 Prog* | 508 Prog* |
(...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1269 gins(AMOVSL, N, N); // MOVL *(SI)+,*(DI)+ | 1279 gins(AMOVSL, N, N); // MOVL *(SI)+,*(DI)+ |
1270 q--; | 1280 q--; |
1271 } | 1281 } |
1272 while(c > 0) { | 1282 while(c > 0) { |
1273 gins(AMOVSB, N, N); // MOVB *(SI)+,*(DI)+ | 1283 gins(AMOVSB, N, N); // MOVB *(SI)+,*(DI)+ |
1274 c--; | 1284 c--; |
1275 } | 1285 } |
1276 } | 1286 } |
1277 } | 1287 } |
1278 | 1288 |
LEFT | RIGHT |