~ubuntu-branches/ubuntu/vivid/golang/vivid

« back to all changes in this revision

Viewing changes to src/cmd/gc/gen.c

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
266
266
        Label *lab;
267
267
        int32 wasregalloc;
268
268
 
 
269
//dump("gen", n);
 
270
 
269
271
        lno = setlineno(n);
270
272
        wasregalloc = anyregalloc();
271
273
 
279
281
 
280
282
        switch(n->op) {
281
283
        default:
282
 
                fatal("gen: unknown op %N", n);
 
284
                fatal("gen: unknown op %+hN", n);
283
285
                break;
284
286
 
285
287
        case OCASE:
394
396
                }
395
397
                gen(n->nincr);                          // contin:      incr
396
398
                patch(p1, pc);                          // test:
397
 
                bgen(n->ntest, 0, breakpc);             //              if(!test) goto break
 
399
                bgen(n->ntest, 0, -1, breakpc);         //              if(!test) goto break
398
400
                genlist(n->nbody);                              //              body
399
401
                gjmp(continpc);
400
402
                patch(breakpc, pc);                     // done:
410
412
                p1 = gjmp(P);                   //              goto test
411
413
                p2 = gjmp(P);                   // p2:          goto else
412
414
                patch(p1, pc);                          // test:
413
 
                bgen(n->ntest, 0, p2);                  //              if(!test) goto p2
 
415
                bgen(n->ntest, 0, -n->likely, p2);              //              if(!test) goto p2
414
416
                genlist(n->nbody);                              //              then
415
417
                p3 = gjmp(P);                   //              goto done
416
418
                patch(p2, pc);                          // else:
489
491
        case ORETURN:
490
492
                cgen_ret(n);
491
493
                break;
 
494
        
 
495
        case OCHECKNOTNIL:
 
496
                checkref(n->left, 1);
492
497
        }
493
498
 
494
499
ret:
509
514
void
510
515
cgen_callmeth(Node *n, int proc)
511
516
{
 
517
        Node n2;
512
518
        Node *l;
513
519
 
514
 
        // generate a rewrite for method call
 
520
        // generate a rewrite in n2 for the method call
515
521
        // (p.f)(...) goes to (f)(p,...)
516
522
 
517
523
        l = n->left;
518
524
        if(l->op != ODOTMETH)
519
525
                fatal("cgen_callmeth: not dotmethod: %N");
520
526
 
521
 
        n->op = OCALLFUNC;
522
 
        n->left = n->left->right;
523
 
        n->left->type = l->type;
 
527
        n2 = *n;
 
528
        n2.op = OCALLFUNC;
 
529
        n2.left = l->right;
 
530
        n2.left->type = l->type;
524
531
 
525
 
        if(n->left->op == ONAME)
526
 
                n->left->class = PFUNC;
527
 
        cgen_call(n, proc);
 
532
        if(n2.left->op == ONAME)
 
533
                n2.left->class = PFUNC;
 
534
        cgen_call(&n2, proc);
528
535
}
529
536
 
530
537
/*
631
638
}
632
639
 
633
640
/*
 
641
 * clearslim generates code to zero a slim node.
 
642
 */
 
643
void
 
644
clearslim(Node *n)
 
645
{
 
646
        Node z;
 
647
        Mpflt zero;
 
648
 
 
649
        memset(&z, 0, sizeof(z));
 
650
        z.op = OLITERAL;
 
651
        z.type = n->type;
 
652
        z.addable = 1;
 
653
 
 
654
        switch(simtype[n->type->etype]) {
 
655
        case TCOMPLEX64:
 
656
        case TCOMPLEX128:
 
657
                z.val.u.cval = mal(sizeof(*z.val.u.cval));
 
658
                mpmovecflt(&z.val.u.cval->real, 0.0);
 
659
                mpmovecflt(&z.val.u.cval->imag, 0.0);
 
660
                break;
 
661
 
 
662
        case TFLOAT32:
 
663
        case TFLOAT64:
 
664
                mpmovecflt(&zero, 0.0);
 
665
                z.val.ctype = CTFLT;
 
666
                z.val.u.fval = &zero;
 
667
                break;
 
668
 
 
669
        case TPTR32:
 
670
        case TPTR64:
 
671
        case TCHAN:
 
672
        case TMAP:
 
673
                z.val.ctype = CTNIL;
 
674
                break;
 
675
 
 
676
        case TBOOL:
 
677
                z.val.ctype = CTBOOL;
 
678
                break;
 
679
 
 
680
        case TINT8:
 
681
        case TINT16:
 
682
        case TINT32:
 
683
        case TINT64:
 
684
        case TUINT8:
 
685
        case TUINT16:
 
686
        case TUINT32:
 
687
        case TUINT64:
 
688
                z.val.ctype = CTINT;
 
689
                z.val.u.xval = mal(sizeof(*z.val.u.xval));
 
690
                mpmovecfix(z.val.u.xval, 0);
 
691
                break;
 
692
 
 
693
        default:
 
694
                fatal("clearslim called on type %T", n->type);
 
695
        }
 
696
 
 
697
        ullmancalc(&z);
 
698
        cgen(&z, n);
 
699
}
 
700
 
 
701
/*
634
702
 * generate assignment:
635
703
 *      nl = nr
636
704
 * nr == N means zero nl.
638
706
void
639
707
cgen_as(Node *nl, Node *nr)
640
708
{
641
 
        Node nc;
642
709
        Type *tl;
643
 
        int iszer;
644
710
 
645
711
        if(debug['g']) {
646
712
                dump("cgen_as", nl);
655
721
                return;
656
722
        }
657
723
 
658
 
        iszer = 0;
659
724
        if(nr == N || isnil(nr)) {
660
725
                // externals and heaps should already be clear
661
726
                if(nr == N) {
670
735
                        return;
671
736
                if(isfat(tl)) {
672
737
                        clearfat(nl);
673
 
                        goto ret;
674
 
                }
675
 
 
676
 
                /* invent a "zero" for the rhs */
677
 
                iszer = 1;
678
 
                nr = &nc;
679
 
                memset(nr, 0, sizeof(*nr));
680
 
                switch(simtype[tl->etype]) {
681
 
                default:
682
 
                        fatal("cgen_as: tl %T", tl);
683
 
                        break;
684
 
 
685
 
                case TINT8:
686
 
                case TUINT8:
687
 
                case TINT16:
688
 
                case TUINT16:
689
 
                case TINT32:
690
 
                case TUINT32:
691
 
                case TINT64:
692
 
                case TUINT64:
693
 
                        nr->val.u.xval = mal(sizeof(*nr->val.u.xval));
694
 
                        mpmovecfix(nr->val.u.xval, 0);
695
 
                        nr->val.ctype = CTINT;
696
 
                        break;
697
 
 
698
 
                case TFLOAT32:
699
 
                case TFLOAT64:
700
 
                        nr->val.u.fval = mal(sizeof(*nr->val.u.fval));
701
 
                        mpmovecflt(nr->val.u.fval, 0.0);
702
 
                        nr->val.ctype = CTFLT;
703
 
                        break;
704
 
 
705
 
                case TBOOL:
706
 
                        nr->val.u.bval = 0;
707
 
                        nr->val.ctype = CTBOOL;
708
 
                        break;
709
 
 
710
 
                case TPTR32:
711
 
                case TPTR64:
712
 
                        nr->val.ctype = CTNIL;
713
 
                        break;
714
 
 
715
 
                case TCOMPLEX64:
716
 
                case TCOMPLEX128:
717
 
                        nr->val.u.cval = mal(sizeof(*nr->val.u.cval));
718
 
                        mpmovecflt(&nr->val.u.cval->real, 0.0);
719
 
                        mpmovecflt(&nr->val.u.cval->imag, 0.0);
720
 
                        break;
721
 
                }
722
 
                nr->op = OLITERAL;
723
 
                nr->type = tl;
724
 
                nr->addable = 1;
725
 
                ullmancalc(nr);
 
738
                        return;
 
739
                }
 
740
                clearslim(nl);
 
741
                return;
726
742
        }
727
743
 
728
744
        tl = nl->type;
730
746
                return;
731
747
 
732
748
        cgen(nr, nl);
733
 
        if(iszer && nl->addable)
734
 
                gused(nl);
735
 
 
736
 
ret:
737
 
        ;
 
749
}
 
750
 
 
751
/*
 
752
 * generate:
 
753
 *      res = iface{typ, data}
 
754
 * n->left is typ
 
755
 * n->right is data
 
756
 */
 
757
void
 
758
cgen_eface(Node *n, Node *res)
 
759
{
 
760
        /* 
 
761
         * the right node of an eface may contain function calls that uses res as an argument,
 
762
         * so it's important that it is done first
 
763
         */
 
764
        Node dst;
 
765
        dst = *res;
 
766
        dst.type = types[tptr];
 
767
        dst.xoffset += widthptr;
 
768
        cgen(n->right, &dst);
 
769
        dst.xoffset -= widthptr;
 
770
        cgen(n->left, &dst);
 
771
}
 
772
 
 
773
/*
 
774
 * generate:
 
775
 *      res = s[lo, hi];
 
776
 * n->left is s
 
777
 * n->list is (cap(s)-lo(TUINT), hi-lo(TUINT)[, lo*width(TUINTPTR)])
 
778
 * caller (cgen) guarantees res is an addable ONAME.
 
779
 */
 
780
void
 
781
cgen_slice(Node *n, Node *res)
 
782
{
 
783
        Node src, dst, *cap, *len, *offs, *add;
 
784
 
 
785
        cap = n->list->n;
 
786
        len = n->list->next->n;
 
787
        offs = N;
 
788
        if(n->list->next->next)
 
789
                offs = n->list->next->next->n;
 
790
 
 
791
        // dst.len = hi [ - lo ]
 
792
        dst = *res;
 
793
        dst.xoffset += Array_nel;
 
794
        dst.type = types[simtype[TUINT]];
 
795
        cgen(len, &dst);
 
796
 
 
797
        if(n->op != OSLICESTR) {
 
798
                // dst.cap = cap [ - lo ]
 
799
                dst = *res;
 
800
                dst.xoffset += Array_cap;
 
801
                dst.type = types[simtype[TUINT]];
 
802
                cgen(cap, &dst);
 
803
        }
 
804
 
 
805
        // dst.array = src.array  [ + lo *width ]
 
806
        dst = *res;
 
807
        dst.xoffset += Array_array;
 
808
        dst.type = types[TUINTPTR];
 
809
 
 
810
        if(n->op == OSLICEARR) {
 
811
                if(!isptr[n->left->type->etype])
 
812
                        fatal("slicearr is supposed to work on pointer: %+N\n", n);
 
813
                checkref(n->left, 0);
 
814
        }
 
815
 
 
816
        if(isnil(n->left)) {
 
817
                tempname(&src, n->left->type);
 
818
                cgen(n->left, &src);
 
819
        } else
 
820
                src = *n->left;
 
821
        src.xoffset += Array_array;
 
822
        src.type = types[TUINTPTR];
 
823
 
 
824
        if(offs == N) {
 
825
                cgen(&src, &dst);
 
826
        } else {
 
827
                add = nod(OADD, &src, offs);
 
828
                typecheck(&add, Erv);
 
829
                cgen(add, &dst);
 
830
        }
738
831
}
739
832
 
740
833
/*
743
836
 * <0 is pointer to next field (+1)
744
837
 */
745
838
int
746
 
dotoffset(Node *n, int *oary, Node **nn)
 
839
dotoffset(Node *n, int64 *oary, Node **nn)
747
840
{
748
841
        int i;
749
842