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 "gg.h" | 5 #include "gg.h" |
6 | 6 |
7 /* | 7 /* |
8 * generate: | 8 * generate: |
9 * res = n; | 9 * res = n; |
10 * simplifies and calls gmove. | 10 * simplifies and calls gmove. |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 } | 411 } |
412 | 412 |
413 /* | 413 /* |
414 * generate: | 414 * generate: |
415 * res = &n; | 415 * res = &n; |
416 */ | 416 */ |
417 void | 417 void |
418 agen(Node *n, Node *res) | 418 agen(Node *n, Node *res) |
419 { | 419 { |
420 Node *nl, *nr; | 420 Node *nl, *nr; |
421 » Node n1, n2, n3, tmp, n4; | 421 » Node n1, n2, n3, tmp, n4, n5; |
422 Prog *p1; | 422 Prog *p1; |
423 uint32 w; | 423 uint32 w; |
424 uint64 v; | 424 uint64 v; |
425 Type *t; | 425 Type *t; |
426 | 426 |
427 if(debug['g']) { | 427 if(debug['g']) { |
428 dump("\nagen-res", res); | 428 dump("\nagen-res", res); |
429 dump("agen-r", n); | 429 dump("agen-r", n); |
430 } | 430 } |
431 if(n == N || n->type == T) | 431 if(n == N || n->type == T) |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 regfree(&n4); | 511 regfree(&n4); |
512 } | 512 } |
513 | 513 |
514 if(w == 0) | 514 if(w == 0) |
515 fatal("index is zero width"); | 515 fatal("index is zero width"); |
516 | 516 |
517 // constant index | 517 // constant index |
518 if(isconst(nr, CTINT)) { | 518 if(isconst(nr, CTINT)) { |
519 v = mpgetfix(nr->val.u.xval); | 519 v = mpgetfix(nr->val.u.xval); |
520 if(isslice(nl->type)) { | 520 if(isslice(nl->type)) { |
521 | |
522 if(!debug['B'] && !n->etype) { | 521 if(!debug['B'] && !n->etype) { |
523 n1 = n3; | 522 n1 = n3; |
524 n1.op = OINDREG; | 523 n1.op = OINDREG; |
525 n1.type = types[tptr]; | 524 n1.type = types[tptr]; |
526 n1.xoffset = Array_nel; | 525 n1.xoffset = Array_nel; |
527 » » » » » nodconst(&n2, types[TUINT64], v); | 526 » » » » » nodconst(&n2, types[TUINT32], v); |
528 gins(optoas(OCMP, types[TUINT32]), &n1,
&n2); | 527 gins(optoas(OCMP, types[TUINT32]), &n1,
&n2); |
529 p1 = gbranch(optoas(OGT, types[TUINT32])
, T); | 528 p1 = gbranch(optoas(OGT, types[TUINT32])
, T); |
530 ginscall(panicindex, 0); | 529 ginscall(panicindex, 0); |
531 patch(p1, pc); | 530 patch(p1, pc); |
532 } | 531 } |
533 | 532 |
534 n1 = n3; | 533 n1 = n3; |
535 n1.op = OINDREG; | 534 n1.op = OINDREG; |
536 n1.type = types[tptr]; | 535 n1.type = types[tptr]; |
537 n1.xoffset = Array_array; | 536 n1.xoffset = Array_array; |
538 gmove(&n1, &n3); | 537 gmove(&n1, &n3); |
539 } else | |
540 if(!debug['B'] && !n->etype) { | |
541 if(v < 0) | |
542 yyerror("out of bounds on array"); | |
543 else | |
544 if(v >= nl->type->bound) | |
545 yyerror("out of bounds on array"); | |
546 } | 538 } |
547 | 539 |
548 nodconst(&n2, types[tptr], v*w); | 540 nodconst(&n2, types[tptr], v*w); |
549 gins(optoas(OADD, types[tptr]), &n2, &n3); | 541 gins(optoas(OADD, types[tptr]), &n2, &n3); |
550 | 542 |
551 gmove(&n3, res); | 543 gmove(&n3, res); |
552 regfree(&n3); | 544 regfree(&n3); |
553 break; | 545 break; |
554 } | 546 } |
555 | 547 |
556 // type of the index | 548 // type of the index |
557 t = types[TUINT64]; | 549 t = types[TUINT64]; |
558 if(issigned[n1.type->etype]) | 550 if(issigned[n1.type->etype]) |
559 t = types[TINT64]; | 551 t = types[TINT64]; |
560 | 552 |
561 regalloc(&n2, t, &n1); // i | 553 regalloc(&n2, t, &n1); // i |
562 gmove(&n1, &n2); | 554 gmove(&n1, &n2); |
563 regfree(&n1); | 555 regfree(&n1); |
564 | 556 |
565 if(!debug['B'] && !n->etype) { | 557 if(!debug['B'] && !n->etype) { |
566 // check bounds | 558 // check bounds |
| 559 n5.op = OXXX; |
| 560 t = types[TUINT32]; |
567 if(isslice(nl->type)) { | 561 if(isslice(nl->type)) { |
568 n1 = n3; | 562 n1 = n3; |
569 n1.op = OINDREG; | 563 n1.op = OINDREG; |
570 » » » » n1.type = types[tptr]; | 564 » » » » n1.type = types[TUINT32]; |
571 n1.xoffset = Array_nel; | 565 n1.xoffset = Array_nel; |
572 » » » } else | 566 » » » » if(is64(nr->type)) { |
573 » » » » nodconst(&n1, types[TUINT64], nl->type->bound); | 567 » » » » » t = types[TUINT64]; |
574 » » » gins(optoas(OCMP, types[TUINT32]), &n2, &n1); | 568 » » » » » regalloc(&n5, t, N); |
575 » » » p1 = gbranch(optoas(OLT, types[TUINT32]), T); | 569 » » » » » gmove(&n1, &n5); |
| 570 » » » » » n1 = n5; |
| 571 » » » » } |
| 572 » » » } else { |
| 573 » » » » if(is64(nr->type)) |
| 574 » » » » » t = types[TUINT64]; |
| 575 » » » » nodconst(&n1, t, nl->type->bound); |
| 576 » » » } |
| 577 » » » gins(optoas(OCMP, t), &n2, &n1); |
| 578 » » » p1 = gbranch(optoas(OLT, t), T); |
| 579 » » » if(n5.op != OXXX) |
| 580 » » » » regfree(&n5); |
576 ginscall(panicindex, 0); | 581 ginscall(panicindex, 0); |
577 patch(p1, pc); | 582 patch(p1, pc); |
578 } | 583 } |
579 | 584 |
580 if(isslice(nl->type)) { | 585 if(isslice(nl->type)) { |
581 n1 = n3; | 586 n1 = n3; |
582 n1.op = OINDREG; | 587 n1.op = OINDREG; |
583 n1.type = types[tptr]; | 588 n1.type = types[tptr]; |
584 n1.xoffset = Array_array; | 589 n1.xoffset = Array_array; |
585 gmove(&n1, &n3); | 590 gmove(&n1, &n3); |
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1092 gins(AMOVSB, N, N); // MOVB *(SI)+,*(DI)+ | 1097 gins(AMOVSB, N, N); // MOVB *(SI)+,*(DI)+ |
1093 c--; | 1098 c--; |
1094 } | 1099 } |
1095 } | 1100 } |
1096 | 1101 |
1097 | 1102 |
1098 restx(&nodl, &oldl); | 1103 restx(&nodl, &oldl); |
1099 restx(&nodr, &oldr); | 1104 restx(&nodr, &oldr); |
1100 restx(&cx, &oldcx); | 1105 restx(&cx, &oldcx); |
1101 } | 1106 } |
OLD | NEW |