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
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:
510
515
cgen_callmeth(Node *n, int proc)
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,...)
518
524
if(l->op != ODOTMETH)
519
525
fatal("cgen_callmeth: not dotmethod: %N");
522
n->left = n->left->right;
523
n->left->type = l->type;
530
n2.left->type = l->type;
525
if(n->left->op == ONAME)
526
n->left->class = PFUNC;
532
if(n2.left->op == ONAME)
533
n2.left->class = PFUNC;
534
cgen_call(&n2, proc);
641
* clearslim generates code to zero a slim node.
649
memset(&z, 0, sizeof(z));
654
switch(simtype[n->type->etype]) {
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);
664
mpmovecflt(&zero, 0.0);
666
z.val.u.fval = &zero;
677
z.val.ctype = CTBOOL;
689
z.val.u.xval = mal(sizeof(*z.val.u.xval));
690
mpmovecfix(z.val.u.xval, 0);
694
fatal("clearslim called on type %T", n->type);
634
702
* generate assignment:
636
704
* nr == N means zero nl.
676
/* invent a "zero" for the rhs */
679
memset(nr, 0, sizeof(*nr));
680
switch(simtype[tl->etype]) {
682
fatal("cgen_as: tl %T", tl);
693
nr->val.u.xval = mal(sizeof(*nr->val.u.xval));
694
mpmovecfix(nr->val.u.xval, 0);
695
nr->val.ctype = CTINT;
700
nr->val.u.fval = mal(sizeof(*nr->val.u.fval));
701
mpmovecflt(nr->val.u.fval, 0.0);
702
nr->val.ctype = CTFLT;
707
nr->val.ctype = CTBOOL;
712
nr->val.ctype = CTNIL;
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);
733
if(iszer && nl->addable)
753
* res = iface{typ, data}
758
cgen_eface(Node *n, Node *res)
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
766
dst.type = types[tptr];
767
dst.xoffset += widthptr;
768
cgen(n->right, &dst);
769
dst.xoffset -= widthptr;
777
* n->list is (cap(s)-lo(TUINT), hi-lo(TUINT)[, lo*width(TUINTPTR)])
778
* caller (cgen) guarantees res is an addable ONAME.
781
cgen_slice(Node *n, Node *res)
783
Node src, dst, *cap, *len, *offs, *add;
786
len = n->list->next->n;
788
if(n->list->next->next)
789
offs = n->list->next->next->n;
791
// dst.len = hi [ - lo ]
793
dst.xoffset += Array_nel;
794
dst.type = types[simtype[TUINT]];
797
if(n->op != OSLICESTR) {
798
// dst.cap = cap [ - lo ]
800
dst.xoffset += Array_cap;
801
dst.type = types[simtype[TUINT]];
805
// dst.array = src.array [ + lo *width ]
807
dst.xoffset += Array_array;
808
dst.type = types[TUINTPTR];
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);
817
tempname(&src, n->left->type);
821
src.xoffset += Array_array;
822
src.type = types[TUINTPTR];
827
add = nod(OADD, &src, offs);
828
typecheck(&add, Erv);
743
836
* <0 is pointer to next field (+1)
746
dotoffset(Node *n, int *oary, Node **nn)
839
dotoffset(Node *n, int64 *oary, Node **nn)