github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/gc/walk.c (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  #include	<u.h>
     6  #include	<libc.h>
     7  #include	"go.h"
     8  
     9  static	Node*	walkprint(Node*, NodeList**, int);
    10  static	Node*	mapfn(char*, Type*);
    11  static	Node*	mapfndel(char*, Type*);
    12  static	Node*	ascompatee1(int, Node*, Node*, NodeList**);
    13  static	NodeList*	ascompatee(int, NodeList*, NodeList*, NodeList**);
    14  static	NodeList*	ascompatet(int, NodeList*, Type**, int, NodeList**);
    15  static	NodeList*	ascompatte(int, Node*, int, Type**, NodeList*, int, NodeList**);
    16  static	Node*	convas(Node*, NodeList**);
    17  static	void	heapmoves(void);
    18  static	NodeList*	paramstoheap(Type **argin, int out);
    19  static	NodeList*	reorder1(NodeList*);
    20  static	NodeList*	reorder3(NodeList*);
    21  static	Node*	addstr(Node*, NodeList**);
    22  static	Node*	appendslice(Node*, NodeList**);
    23  static	Node*	append(Node*, NodeList**);
    24  static	Node*	copyany(Node*, NodeList**);
    25  static	Node*	sliceany(Node*, NodeList**);
    26  static	void	walkcompare(Node**, NodeList**);
    27  static	void	walkrotate(Node**);
    28  static	void	walkmul(Node**, NodeList**);
    29  static	void	walkdiv(Node**, NodeList**);
    30  static	int	bounded(Node*, int64);
    31  static	Mpint	mpzero;
    32  
    33  void
    34  walk(Node *fn)
    35  {
    36  	char s[50];
    37  	NodeList *l;
    38  	int lno;
    39  
    40  	curfn = fn;
    41  
    42  	if(debug['W']) {
    43  		snprint(s, sizeof(s), "\nbefore %S", curfn->nname->sym);
    44  		dumplist(s, curfn->nbody);
    45  	}
    46  
    47  	lno = lineno;
    48  
    49  	// Final typecheck for any unused variables.
    50  	// It's hard to be on the heap when not-used, but best to be consistent about &~PHEAP here and below.
    51  	for(l=fn->dcl; l; l=l->next)
    52  		if(l->n->op == ONAME && (l->n->class&~PHEAP) == PAUTO)
    53  			typecheck(&l->n, Erv | Easgn);
    54  
    55  	// Propagate the used flag for typeswitch variables up to the NONAME in it's definition.
    56  	for(l=fn->dcl; l; l=l->next)
    57  		if(l->n->op == ONAME && (l->n->class&~PHEAP) == PAUTO && l->n->defn && l->n->defn->op == OTYPESW && l->n->used)
    58  			l->n->defn->left->used++;
    59  	
    60  	for(l=fn->dcl; l; l=l->next) {
    61  		if(l->n->op != ONAME || (l->n->class&~PHEAP) != PAUTO || l->n->sym->name[0] == '&' || l->n->used)
    62  			continue;
    63  		if(l->n->defn && l->n->defn->op == OTYPESW) {
    64  			if(l->n->defn->left->used)
    65  				continue;
    66  			lineno = l->n->defn->left->lineno;
    67  			yyerror("%S declared and not used", l->n->sym);
    68  			l->n->defn->left->used = 1; // suppress repeats
    69  		} else {
    70  			lineno = l->n->lineno;
    71  			yyerror("%S declared and not used", l->n->sym);
    72  		}
    73  	}	
    74  
    75  	lineno = lno;
    76  	if(nerrors != 0)
    77  		return;
    78  	walkstmtlist(curfn->nbody);
    79  	if(debug['W']) {
    80  		snprint(s, sizeof(s), "after walk %S", curfn->nname->sym);
    81  		dumplist(s, curfn->nbody);
    82  	}
    83  	heapmoves();
    84  	if(debug['W'] && curfn->enter != nil) {
    85  		snprint(s, sizeof(s), "enter %S", curfn->nname->sym);
    86  		dumplist(s, curfn->enter);
    87  	}
    88  }
    89  
    90  
    91  void
    92  walkstmtlist(NodeList *l)
    93  {
    94  	for(; l; l=l->next)
    95  		walkstmt(&l->n);
    96  }
    97  
    98  static int
    99  samelist(NodeList *a, NodeList *b)
   100  {
   101  	for(; a && b; a=a->next, b=b->next)
   102  		if(a->n != b->n)
   103  			return 0;
   104  	return a == b;
   105  }
   106  
   107  static int
   108  paramoutheap(Node *fn)
   109  {
   110  	NodeList *l;
   111  
   112  	for(l=fn->dcl; l; l=l->next) {
   113  		switch(l->n->class) {
   114  		case PPARAMOUT:
   115  		case PPARAMOUT|PHEAP:
   116  			return l->n->addrtaken;
   117  		case PAUTO:
   118  		case PAUTO|PHEAP:
   119  			// stop early - parameters are over
   120  			return 0;
   121  		}
   122  	}
   123  	return 0;
   124  }
   125  
   126  void
   127  walkstmt(Node **np)
   128  {
   129  	NodeList *init;
   130  	NodeList *ll, *rl;
   131  	int cl;
   132  	Node *n, *f;
   133  
   134  	n = *np;
   135  	if(n == N)
   136  		return;
   137  
   138  	setlineno(n);
   139  
   140  	walkstmtlist(n->ninit);
   141  
   142  	switch(n->op) {
   143  	default:
   144  		if(n->op == ONAME)
   145  			yyerror("%S is not a top level statement", n->sym);
   146  		else
   147  			yyerror("%O is not a top level statement", n->op);
   148  		dump("nottop", n);
   149  		break;
   150  
   151  	case OAS:
   152  	case OASOP:
   153  	case OAS2:
   154  	case OAS2DOTTYPE:
   155  	case OAS2RECV:
   156  	case OAS2FUNC:
   157  	case OAS2MAPR:
   158  	case OCLOSE:
   159  	case OCOPY:
   160  	case OCALLMETH:
   161  	case OCALLINTER:
   162  	case OCALL:
   163  	case OCALLFUNC:
   164  	case ODELETE:
   165  	case OSEND:
   166  	case ORECV:
   167  	case OPRINT:
   168  	case OPRINTN:
   169  	case OPANIC:
   170  	case OEMPTY:
   171  	case ORECOVER:
   172  		if(n->typecheck == 0)
   173  			fatal("missing typecheck: %+N", n);
   174  		init = n->ninit;
   175  		n->ninit = nil;
   176  		walkexpr(&n, &init);
   177  		addinit(&n, init);
   178  		if((*np)->op == OCOPY && n->op == OCONVNOP)
   179  			n->op = OEMPTY; // don't leave plain values as statements.
   180  		break;
   181  
   182  	case OBREAK:
   183  	case ODCL:
   184  	case OCONTINUE:
   185  	case OFALL:
   186  	case OGOTO:
   187  	case OLABEL:
   188  	case ODCLCONST:
   189  	case ODCLTYPE:
   190  	case OCHECKNIL:
   191  		break;
   192  
   193  	case OBLOCK:
   194  		walkstmtlist(n->list);
   195  		break;
   196  
   197  	case OXCASE:
   198  		yyerror("case statement out of place");
   199  		n->op = OCASE;
   200  	case OCASE:
   201  		walkstmt(&n->right);
   202  		break;
   203  
   204  	case ODEFER:
   205  		hasdefer = 1;
   206  		switch(n->left->op) {
   207  		case OPRINT:
   208  		case OPRINTN:
   209  			walkexprlist(n->left->list, &n->ninit);
   210  			n->left = walkprint(n->left, &n->ninit, 1);
   211  			break;
   212  		default:
   213  			walkexpr(&n->left, &n->ninit);
   214  			break;
   215  		}
   216  		break;
   217  
   218  	case OFOR:
   219  		if(n->ntest != N) {
   220  			walkstmtlist(n->ntest->ninit);
   221  			init = n->ntest->ninit;
   222  			n->ntest->ninit = nil;
   223  			walkexpr(&n->ntest, &init);
   224  			addinit(&n->ntest, init);
   225  		}
   226  		walkstmt(&n->nincr);
   227  		walkstmtlist(n->nbody);
   228  		break;
   229  
   230  	case OIF:
   231  		walkexpr(&n->ntest, &n->ninit);
   232  		walkstmtlist(n->nbody);
   233  		walkstmtlist(n->nelse);
   234  		break;
   235  
   236  	case OPROC:
   237  		switch(n->left->op) {
   238  		case OPRINT:
   239  		case OPRINTN:
   240  			walkexprlist(n->left->list, &n->ninit);
   241  			n->left = walkprint(n->left, &n->ninit, 1);
   242  			break;
   243  		default:
   244  			walkexpr(&n->left, &n->ninit);
   245  			break;
   246  		}
   247  		break;
   248  
   249  	case ORETURN:
   250  		walkexprlist(n->list, &n->ninit);
   251  		if(n->list == nil)
   252  			break;
   253  		if((curfn->type->outnamed && count(n->list) > 1) || paramoutheap(curfn)) {
   254  			// assign to the function out parameters,
   255  			// so that reorder3 can fix up conflicts
   256  			rl = nil;
   257  			for(ll=curfn->dcl; ll != nil; ll=ll->next) {
   258  				cl = ll->n->class & ~PHEAP;
   259  				if(cl == PAUTO)
   260  					break;
   261  				if(cl == PPARAMOUT)
   262  					rl = list(rl, ll->n);
   263  			}
   264  			if(samelist(rl, n->list)) {
   265  				// special return in disguise
   266  				n->list = nil;
   267  				break;
   268  			}
   269  			if(count(n->list) == 1 && count(rl) > 1) {
   270  				// OAS2FUNC in disguise
   271  				f = n->list->n;
   272  				if(f->op != OCALLFUNC && f->op != OCALLMETH && f->op != OCALLINTER)
   273  					fatal("expected return of call, have %N", f);
   274  				n->list = concat(list1(f), ascompatet(n->op, rl, &f->type, 0, &n->ninit));
   275  				break;
   276  			}
   277  
   278  			// move function calls out, to make reorder3's job easier.
   279  			walkexprlistsafe(n->list, &n->ninit);
   280  			ll = ascompatee(n->op, rl, n->list, &n->ninit);
   281  			n->list = reorder3(ll);
   282  			break;
   283  		}
   284  		ll = ascompatte(n->op, nil, 0, getoutarg(curfn->type), n->list, 1, &n->ninit);
   285  		n->list = ll;
   286  		break;
   287  
   288  	case ORETJMP:
   289  		break;
   290  
   291  	case OSELECT:
   292  		walkselect(n);
   293  		break;
   294  
   295  	case OSWITCH:
   296  		walkswitch(n);
   297  		break;
   298  
   299  	case ORANGE:
   300  		walkrange(n);
   301  		break;
   302  
   303  	case OXFALL:
   304  		yyerror("fallthrough statement out of place");
   305  		n->op = OFALL;
   306  		break;
   307  	}
   308  
   309  	if(n->op == ONAME)
   310  		fatal("walkstmt ended up with name: %+N", n);
   311  	
   312  	*np = n;
   313  }
   314  
   315  
   316  /*
   317   * walk the whole tree of the body of an
   318   * expression or simple statement.
   319   * the types expressions are calculated.
   320   * compile-time constants are evaluated.
   321   * complex side effects like statements are appended to init
   322   */
   323  
   324  void
   325  walkexprlist(NodeList *l, NodeList **init)
   326  {
   327  	for(; l; l=l->next)
   328  		walkexpr(&l->n, init);
   329  }
   330  
   331  void
   332  walkexprlistsafe(NodeList *l, NodeList **init)
   333  {
   334  	for(; l; l=l->next) {
   335  		l->n = safeexpr(l->n, init);
   336  		walkexpr(&l->n, init);
   337  	}
   338  }
   339  
   340  void
   341  walkexpr(Node **np, NodeList **init)
   342  {
   343  	Node *r, *l, *var, *a;
   344  	NodeList *ll, *lr, *lpost;
   345  	Type *t;
   346  	int et, old_safemode;
   347  	int64 v;
   348  	int32 lno;
   349  	Node *n, *fn, *n1, *n2;
   350  	Sym *sym;
   351  	char buf[100], *p;
   352  
   353  	n = *np;
   354  
   355  	if(n == N)
   356  		return;
   357  
   358  	if(init == &n->ninit) {
   359  		// not okay to use n->ninit when walking n,
   360  		// because we might replace n with some other node
   361  		// and would lose the init list.
   362  		fatal("walkexpr init == &n->ninit");
   363  	}
   364  
   365  	if(n->ninit != nil) {
   366  		walkstmtlist(n->ninit);
   367  		*init = concat(*init, n->ninit);
   368  		n->ninit = nil;
   369  	}
   370  
   371  	// annoying case - not typechecked
   372  	if(n->op == OKEY) {
   373  		walkexpr(&n->left, init);
   374  		walkexpr(&n->right, init);
   375  		return;
   376  	}
   377  
   378  	lno = setlineno(n);
   379  
   380  	if(debug['w'] > 1)
   381  		dump("walk-before", n);
   382  
   383  	if(n->typecheck != 1)
   384  		fatal("missed typecheck: %+N\n", n);
   385  
   386  	switch(n->op) {
   387  	default:
   388  		dump("walk", n);
   389  		fatal("walkexpr: switch 1 unknown op %+hN", n);
   390  		break;
   391  
   392  	case OTYPE:
   393  	case ONONAME:
   394  	case OINDREG:
   395  	case OEMPTY:
   396  		goto ret;
   397  
   398  	case ONOT:
   399  	case OMINUS:
   400  	case OPLUS:
   401  	case OCOM:
   402  	case OREAL:
   403  	case OIMAG:
   404  	case ODOTMETH:
   405  	case ODOTINTER:
   406  		walkexpr(&n->left, init);
   407  		goto ret;
   408  
   409  	case OIND:
   410  		walkexpr(&n->left, init);
   411  		goto ret;
   412  
   413  	case ODOT:
   414  		usefield(n);
   415  		walkexpr(&n->left, init);
   416  		goto ret;
   417  
   418  	case ODOTPTR:
   419  		usefield(n);
   420  		if(n->op == ODOTPTR && n->left->type->type->width == 0) {
   421  			// No actual copy will be generated, so emit an explicit nil check.
   422  			n->left = cheapexpr(n->left, init);
   423  			checknil(n->left, init);
   424  		}
   425  		walkexpr(&n->left, init);
   426  		goto ret;
   427  
   428  	case OEFACE:
   429  		walkexpr(&n->left, init);
   430  		walkexpr(&n->right, init);
   431  		goto ret;
   432  
   433  	case OSPTR:
   434  	case OITAB:
   435  		walkexpr(&n->left, init);
   436  		goto ret;
   437  
   438  	case OLEN:
   439  	case OCAP:
   440  		walkexpr(&n->left, init);
   441  
   442  		// replace len(*[10]int) with 10.
   443  		// delayed until now to preserve side effects.
   444  		t = n->left->type;
   445  		if(isptr[t->etype])
   446  			t = t->type;
   447  		if(isfixedarray(t)) {
   448  			safeexpr(n->left, init);
   449  			nodconst(n, n->type, t->bound);
   450  			n->typecheck = 1;
   451  		}
   452  		goto ret;
   453  
   454  	case OLSH:
   455  	case ORSH:
   456  		walkexpr(&n->left, init);
   457  		walkexpr(&n->right, init);
   458  	shiftwalked:
   459  		t = n->left->type;
   460  		n->bounded = bounded(n->right, 8*t->width);
   461  		if(debug['m'] && n->etype && !isconst(n->right, CTINT))
   462  			warn("shift bounds check elided");
   463  		goto ret;
   464  
   465  	case OAND:
   466  	case OSUB:
   467  	case OHMUL:
   468  	case OLT:
   469  	case OLE:
   470  	case OGE:
   471  	case OGT:
   472  	case OADD:
   473  	case OCOMPLEX:
   474  	case OLROT:
   475  		walkexpr(&n->left, init);
   476  		walkexpr(&n->right, init);
   477  		goto ret;
   478  
   479  	case OOR:
   480  	case OXOR:
   481  		walkexpr(&n->left, init);
   482  		walkexpr(&n->right, init);
   483  		walkrotate(&n);
   484  		goto ret;
   485  
   486  	case OEQ:
   487  	case ONE:
   488  		walkexpr(&n->left, init);
   489  		walkexpr(&n->right, init);
   490  		// Disable safemode while compiling this code: the code we
   491  		// generate internally can refer to unsafe.Pointer.
   492  		// In this case it can happen if we need to generate an ==
   493  		// for a struct containing a reflect.Value, which itself has
   494  		// an unexported field of type unsafe.Pointer.
   495  		old_safemode = safemode;
   496  		safemode = 0;
   497  		walkcompare(&n, init);
   498  		safemode = old_safemode;
   499  		goto ret;
   500  
   501  	case OANDAND:
   502  	case OOROR:
   503  		walkexpr(&n->left, init);
   504  		// cannot put side effects from n->right on init,
   505  		// because they cannot run before n->left is checked.
   506  		// save elsewhere and store on the eventual n->right.
   507  		ll = nil;
   508  		walkexpr(&n->right, &ll);
   509  		addinit(&n->right, ll);
   510  		goto ret;
   511  
   512  	case OPRINT:
   513  	case OPRINTN:
   514  		walkexprlist(n->list, init);
   515  		n = walkprint(n, init, 0);
   516  		goto ret;
   517  
   518  	case OPANIC:
   519  		n = mkcall("panic", T, init, n->left);
   520  		goto ret;
   521  
   522  	case ORECOVER:
   523  		n = mkcall("recover", n->type, init, nod(OADDR, nodfp, N));
   524  		goto ret;
   525  
   526  	case OLITERAL:
   527  		n->addable = 1;
   528  		goto ret;
   529  
   530  	case OCLOSUREVAR:
   531  	case OCFUNC:
   532  		n->addable = 1;
   533  		goto ret;
   534  
   535  	case ONAME:
   536  		if(!(n->class & PHEAP) && n->class != PPARAMREF)
   537  			n->addable = 1;
   538  		goto ret;
   539  
   540  	case OCALLINTER:
   541  		t = n->left->type;
   542  		if(n->list && n->list->n->op == OAS)
   543  			goto ret;
   544  		walkexpr(&n->left, init);
   545  		walkexprlist(n->list, init);
   546  		ll = ascompatte(n->op, n, n->isddd, getinarg(t), n->list, 0, init);
   547  		n->list = reorder1(ll);
   548  		goto ret;
   549  
   550  	case OCALLFUNC:
   551  		t = n->left->type;
   552  		if(n->list && n->list->n->op == OAS)
   553  			goto ret;
   554  
   555  		walkexpr(&n->left, init);
   556  		walkexprlist(n->list, init);
   557  
   558  		ll = ascompatte(n->op, n, n->isddd, getinarg(t), n->list, 0, init);
   559  		n->list = reorder1(ll);
   560  		goto ret;
   561  
   562  	case OCALLMETH:
   563  		t = n->left->type;
   564  		if(n->list && n->list->n->op == OAS)
   565  			goto ret;
   566  		walkexpr(&n->left, init);
   567  		walkexprlist(n->list, init);
   568  		ll = ascompatte(n->op, n, 0, getthis(t), list1(n->left->left), 0, init);
   569  		lr = ascompatte(n->op, n, n->isddd, getinarg(t), n->list, 0, init);
   570  		ll = concat(ll, lr);
   571  		n->left->left = N;
   572  		ullmancalc(n->left);
   573  		n->list = reorder1(ll);
   574  		goto ret;
   575  
   576  	case OAS:
   577  		*init = concat(*init, n->ninit);
   578  		n->ninit = nil;
   579  		walkexpr(&n->left, init);
   580  		n->left = safeexpr(n->left, init);
   581  
   582  		if(oaslit(n, init))
   583  			goto ret;
   584  
   585  		walkexpr(&n->right, init);
   586  		if(n->left != N && n->right != N) {
   587  			r = convas(nod(OAS, n->left, n->right), init);
   588  			r->dodata = n->dodata;
   589  			n = r;
   590  		}
   591  
   592  		goto ret;
   593  
   594  	case OAS2:
   595  		*init = concat(*init, n->ninit);
   596  		n->ninit = nil;
   597  		walkexprlistsafe(n->list, init);
   598  		walkexprlistsafe(n->rlist, init);
   599  		ll = ascompatee(OAS, n->list, n->rlist, init);
   600  		ll = reorder3(ll);
   601  		n = liststmt(ll);
   602  		goto ret;
   603  
   604  	case OAS2FUNC:
   605  	as2func:
   606  		// a,b,... = fn()
   607  		*init = concat(*init, n->ninit);
   608  		n->ninit = nil;
   609  		r = n->rlist->n;
   610  		walkexprlistsafe(n->list, init);
   611  		walkexpr(&r, init);
   612  		l = n->list->n;
   613  
   614  		// all the really hard stuff - explicit function calls and so on -
   615  		// is gone, but map assignments remain.
   616  		// if there are map assignments here, assign via
   617  		// temporaries, because ascompatet assumes
   618  		// the targets can be addressed without function calls
   619  		// and map index has an implicit one.
   620  		lpost = nil;
   621  		if(l->op == OINDEXMAP) {
   622  			var = temp(l->type);
   623  			n->list->n = var;
   624  			a = nod(OAS, l, var);
   625  			typecheck(&a, Etop);
   626  			lpost = list(lpost, a);
   627  		}
   628  		l = n->list->next->n;
   629  		if(l->op == OINDEXMAP) {
   630  			var = temp(l->type);
   631  			n->list->next->n = var;
   632  			a = nod(OAS, l, var);
   633  			typecheck(&a, Etop);
   634  			lpost = list(lpost, a);
   635  		}
   636  		ll = ascompatet(n->op, n->list, &r->type, 0, init);
   637  		walkexprlist(lpost, init);
   638  		n = liststmt(concat(concat(list1(r), ll), lpost));
   639  		goto ret;
   640  
   641  	case OAS2RECV:
   642  		*init = concat(*init, n->ninit);
   643  		n->ninit = nil;
   644  		r = n->rlist->n;
   645  		walkexprlistsafe(n->list, init);
   646  		walkexpr(&r->left, init);
   647  		fn = chanfn("chanrecv2", 2, r->left->type);
   648  		r = mkcall1(fn, getoutargx(fn->type), init, typename(r->left->type), r->left);
   649  		n->rlist->n = r;
   650  		n->op = OAS2FUNC;
   651  		goto as2func;
   652  
   653  	case OAS2MAPR:
   654  		// a,b = m[i];
   655  		*init = concat(*init, n->ninit);
   656  		n->ninit = nil;
   657  		r = n->rlist->n;
   658  		walkexprlistsafe(n->list, init);
   659  		walkexpr(&r->left, init);
   660  		t = r->left->type;
   661  		p = nil;
   662  		if(t->type->width <= 128) { // Check ../../pkg/runtime/hashmap.c:MAXVALUESIZE before changing.
   663  			switch(simsimtype(t->down)) {
   664  			case TINT32:
   665  			case TUINT32:
   666  				p = "mapaccess2_fast32";
   667  				break;
   668  			case TINT64:
   669  			case TUINT64:
   670  				p = "mapaccess2_fast64";
   671  				break;
   672  			case TSTRING:
   673  				p = "mapaccess2_faststr";
   674  				break;
   675  			}
   676  		}
   677  		if(p != nil) {
   678  			// from:
   679  			//   a,b = m[i]
   680  			// to:
   681  			//   var,b = mapaccess2_fast*(t, m, i)
   682  			//   a = *var
   683  			a = n->list->n;
   684  			var = temp(ptrto(t->type));
   685  			var->typecheck = 1;
   686  
   687  			fn = mapfn(p, t);
   688  			r = mkcall1(fn, getoutargx(fn->type), init, typename(t), r->left, r->right);
   689  			n->rlist = list1(r);
   690  			n->op = OAS2FUNC;
   691  			n->list->n = var;
   692  			walkexpr(&n, init);
   693  			*init = list(*init, n);
   694  
   695  			n = nod(OAS, a, nod(OIND, var, N));
   696  			typecheck(&n, Etop);
   697  			walkexpr(&n, init);
   698  			goto ret;
   699  		}
   700  		fn = mapfn("mapaccess2", t);
   701  		r = mkcall1(fn, getoutargx(fn->type), init, typename(t), r->left, r->right);
   702  		n->rlist = list1(r);
   703  		n->op = OAS2FUNC;
   704  		goto as2func;
   705  
   706  	case ODELETE:
   707  		*init = concat(*init, n->ninit);
   708  		n->ninit = nil;
   709  		l = n->list->n;
   710  		r = n->list->next->n;
   711  		t = l->type;
   712  		n = mkcall1(mapfndel("mapdelete", t), t->down, init, typename(t), l, r);
   713  		goto ret;
   714  
   715  	case OAS2DOTTYPE:
   716  		// a,b = i.(T)
   717  		*init = concat(*init, n->ninit);
   718  		n->ninit = nil;
   719  		r = n->rlist->n;
   720  		walkexprlistsafe(n->list, init);
   721  		if(isblank(n->list->n) && !isinter(r->type)) {
   722  			strcpy(buf, "assert");
   723  			p = buf+strlen(buf);
   724  			if(isnilinter(r->left->type))
   725  				*p++ = 'E';
   726  			else
   727  				*p++ = 'I';
   728  			*p++ = '2';
   729  			*p++ = 'T';
   730  			*p++ = 'O';
   731  			*p++ = 'K';
   732  			*p = '\0';
   733  			
   734  			fn = syslook(buf, 1);
   735  			ll = list1(typename(r->type));
   736  			ll = list(ll, r->left);
   737  			argtype(fn, r->left->type);
   738  			n1 = nod(OCALL, fn, N);
   739  			n1->list = ll;
   740  			n = nod(OAS, n->list->next->n, n1);
   741  			typecheck(&n, Etop);
   742  			walkexpr(&n, init);
   743  			goto ret;
   744  		}
   745  
   746  		r->op = ODOTTYPE2;
   747  		walkexpr(&r, init);
   748  		ll = ascompatet(n->op, n->list, &r->type, 0, init);
   749  		n = liststmt(concat(list1(r), ll));
   750  		goto ret;
   751  
   752  	case ODOTTYPE:
   753  	case ODOTTYPE2:
   754  		// Build name of function: assertI2E2 etc.
   755  		strcpy(buf, "assert");
   756  		p = buf+strlen(buf);
   757  		if(isnilinter(n->left->type))
   758  			*p++ = 'E';
   759  		else
   760  			*p++ = 'I';
   761  		*p++ = '2';
   762  		if(isnilinter(n->type))
   763  			*p++ = 'E';
   764  		else if(isinter(n->type))
   765  			*p++ = 'I';
   766  		else
   767  			*p++ = 'T';
   768  		if(n->op == ODOTTYPE2)
   769  			*p++ = '2';
   770  		*p = '\0';
   771  
   772  		fn = syslook(buf, 1);
   773  		ll = list1(typename(n->type));
   774  		ll = list(ll, n->left);
   775  		argtype(fn, n->left->type);
   776  		argtype(fn, n->type);
   777  		n = nod(OCALL, fn, N);
   778  		n->list = ll;
   779  		typecheck(&n, Erv | Efnstruct);
   780  		walkexpr(&n, init);
   781  		goto ret;
   782  
   783  	case OCONVIFACE:
   784  		walkexpr(&n->left, init);
   785  
   786  		// Optimize convT2E as a two-word copy when T is uintptr-shaped.
   787  		if(!isinter(n->left->type) && isnilinter(n->type) &&
   788  		   (n->left->type->width == widthptr) &&
   789  		   isint[simsimtype(n->left->type)]) {
   790  			l = nod(OEFACE, typename(n->left->type), n->left);
   791  			l->type = n->type;
   792  			l->typecheck = n->typecheck;
   793  			n = l;
   794  			goto ret;
   795  		}
   796  
   797  		// Build name of function: convI2E etc.
   798  		// Not all names are possible
   799  		// (e.g., we'll never generate convE2E or convE2I).
   800  		strcpy(buf, "conv");
   801  		p = buf+strlen(buf);
   802  		if(isnilinter(n->left->type))
   803  			*p++ = 'E';
   804  		else if(isinter(n->left->type))
   805  			*p++ = 'I';
   806  		else
   807  			*p++ = 'T';
   808  		*p++ = '2';
   809  		if(isnilinter(n->type))
   810  			*p++ = 'E';
   811  		else
   812  			*p++ = 'I';
   813  		*p = '\0';
   814  
   815  		fn = syslook(buf, 1);
   816  		ll = nil;
   817  		if(!isinter(n->left->type))
   818  			ll = list(ll, typename(n->left->type));
   819  		if(!isnilinter(n->type))
   820  			ll = list(ll, typename(n->type));
   821  		if(!isinter(n->left->type) && !isnilinter(n->type)){
   822  			sym = pkglookup(smprint("%-T.%-T", n->left->type, n->type), itabpkg);
   823  			if(sym->def == N) {
   824  				l = nod(ONAME, N, N);
   825  				l->sym = sym;
   826  				l->type = ptrto(types[TUINT8]);
   827  				l->addable = 1;
   828  				l->class = PEXTERN;
   829  				l->xoffset = 0;
   830  				sym->def = l;
   831  				ggloblsym(sym, widthptr, 1, 0);
   832  			}
   833  			l = nod(OADDR, sym->def, N);
   834  			l->addable = 1;
   835  			ll = list(ll, l);
   836  
   837  			if(n->left->type->width == widthptr &&
   838  		   	   isint[simsimtype(n->left->type)]) {
   839  				/* For pointer types, we can make a special form of optimization
   840  				 *
   841  				 * These statements are put onto the expression init list:
   842  				 * 	Itab *tab = atomicloadtype(&cache);
   843  				 * 	if(tab == nil)
   844  				 * 		tab = typ2Itab(type, itype, &cache);
   845  				 *
   846  				 * The CONVIFACE expression is replaced with this:
   847  				 * 	OEFACE{tab, ptr};
   848  				 */
   849  				l = temp(ptrto(types[TUINT8]));
   850  
   851  				n1 = nod(OAS, l, sym->def);
   852  				typecheck(&n1, Etop);
   853  				*init = list(*init, n1);
   854  
   855  				fn = syslook("typ2Itab", 1);
   856  				n1 = nod(OCALL, fn, N);
   857  				n1->list = ll;
   858  				typecheck(&n1, Erv);
   859  				walkexpr(&n1, init);
   860  
   861  				n2 = nod(OIF, N, N);
   862  				n2->ntest = nod(OEQ, l, nodnil());
   863  				n2->nbody = list1(nod(OAS, l, n1));
   864  				n2->likely = -1;
   865  				typecheck(&n2, Etop);
   866  				*init = list(*init, n2);
   867  
   868  				l = nod(OEFACE, l, n->left);
   869  				l->typecheck = n->typecheck; 
   870  				l->type = n->type;
   871  				n = l;
   872  				goto ret;
   873  			}
   874  		}
   875  		ll = list(ll, n->left);
   876  		argtype(fn, n->left->type);
   877  		argtype(fn, n->type);
   878  		dowidth(fn->type);
   879  		n = nod(OCALL, fn, N);
   880  		n->list = ll;
   881  		typecheck(&n, Erv);
   882  		walkexpr(&n, init);
   883  		goto ret;
   884  
   885  	case OCONV:
   886  	case OCONVNOP:
   887  		if(thechar == '5') {
   888  			if(isfloat[n->left->type->etype]) {
   889  				if(n->type->etype == TINT64) {
   890  					n = mkcall("float64toint64", n->type, init, conv(n->left, types[TFLOAT64]));
   891  					goto ret;
   892  				}
   893  				if(n->type->etype == TUINT64) {
   894  					n = mkcall("float64touint64", n->type, init, conv(n->left, types[TFLOAT64]));
   895  					goto ret;
   896  				}
   897  			}
   898  			if(isfloat[n->type->etype]) {
   899  				if(n->left->type->etype == TINT64) {
   900  					n = mkcall("int64tofloat64", n->type, init, conv(n->left, types[TINT64]));
   901  					goto ret;
   902  				}
   903  				if(n->left->type->etype == TUINT64) {
   904  					n = mkcall("uint64tofloat64", n->type, init, conv(n->left, types[TUINT64]));
   905  					goto ret;
   906  				}
   907  			}
   908  		}
   909  		walkexpr(&n->left, init);
   910  		goto ret;
   911  
   912  	case OASOP:
   913  		if(n->etype == OANDNOT) {
   914  			n->etype = OAND;
   915  			n->right = nod(OCOM, n->right, N);
   916  			typecheck(&n->right, Erv);
   917  		}
   918  		n->left = safeexpr(n->left, init);
   919  		walkexpr(&n->left, init);
   920  		l = n->left;
   921  		walkexpr(&n->right, init);
   922  
   923  		/*
   924  		 * on 32-bit arch, rewrite 64-bit ops into l = l op r.
   925  		 * on 386, rewrite float ops into l = l op r.
   926  		 * everywhere, rewrite map ops into l = l op r.
   927  		 * everywhere, rewrite string += into l = l op r.
   928  		 * everywhere, rewrite integer/complex /= into l = l op r.
   929  		 * TODO(rsc): Maybe this rewrite should be done always?
   930  		 */
   931  		et = n->left->type->etype;
   932  		if((widthptr == 4 && (et == TUINT64 || et == TINT64)) ||
   933  		   (thechar == '8' && isfloat[et]) ||
   934  		   l->op == OINDEXMAP ||
   935  		   et == TSTRING ||
   936  		   (!isfloat[et] && n->etype == ODIV) ||
   937  		   n->etype == OMOD) {
   938  			l = safeexpr(n->left, init);
   939  			a = l;
   940  			if(a->op == OINDEXMAP) {
   941  				// map index has "lhs" bit set in a->etype.
   942  				// make a copy so we can clear it on the rhs.
   943  				a = nod(OXXX, N, N);
   944  				*a = *l;
   945  				a->etype = 0;
   946  			}
   947  			r = nod(OAS, l, nod(n->etype, a, n->right));
   948  			typecheck(&r, Etop);
   949  			walkexpr(&r, init);
   950  			n = r;
   951  			goto ret;
   952  		}
   953  		if(n->etype == OLSH || n->etype == ORSH)
   954  			goto shiftwalked;
   955  		goto ret;
   956  
   957  	case OANDNOT:
   958  		walkexpr(&n->left, init);
   959  		n->op = OAND;
   960  		n->right = nod(OCOM, n->right, N);
   961  		typecheck(&n->right, Erv);
   962  		walkexpr(&n->right, init);
   963  		goto ret;
   964  
   965  	case OMUL:
   966  		walkexpr(&n->left, init);
   967  		walkexpr(&n->right, init);
   968  		walkmul(&n, init);
   969  		goto ret;
   970  
   971  	case ODIV:
   972  	case OMOD:
   973  		walkexpr(&n->left, init);
   974  		walkexpr(&n->right, init);
   975  		/*
   976  		 * rewrite complex div into function call.
   977  		 */
   978  		et = n->left->type->etype;
   979  		if(iscomplex[et] && n->op == ODIV) {
   980  			t = n->type;
   981  			n = mkcall("complex128div", types[TCOMPLEX128], init,
   982  				conv(n->left, types[TCOMPLEX128]),
   983  				conv(n->right, types[TCOMPLEX128]));
   984  			n = conv(n, t);
   985  			goto ret;
   986  		}
   987  		// Nothing to do for float divisions.
   988  		if(isfloat[et])
   989  			goto ret;
   990  
   991  		// Try rewriting as shifts or magic multiplies.
   992  		walkdiv(&n, init);
   993  
   994  		/*
   995  		 * rewrite 64-bit div and mod into function calls
   996  		 * on 32-bit architectures.
   997  		 */
   998  		switch(n->op) {
   999  		case OMOD:
  1000  		case ODIV:
  1001  			if(widthptr > 4 || (et != TUINT64 && et != TINT64))
  1002  				goto ret;
  1003  			if(et == TINT64)
  1004  				strcpy(namebuf, "int64");
  1005  			else
  1006  				strcpy(namebuf, "uint64");
  1007  			if(n->op == ODIV)
  1008  				strcat(namebuf, "div");
  1009  			else
  1010  				strcat(namebuf, "mod");
  1011  			n = mkcall(namebuf, n->type, init,
  1012  				conv(n->left, types[et]), conv(n->right, types[et]));
  1013  			break;
  1014  		default:
  1015  			break;
  1016  		}
  1017  		goto ret;
  1018  
  1019  	case OINDEX:
  1020  		walkexpr(&n->left, init);
  1021  		// save the original node for bounds checking elision.
  1022  		// If it was a ODIV/OMOD walk might rewrite it.
  1023  		r = n->right;
  1024  		walkexpr(&n->right, init);
  1025  
  1026  		// if range of type cannot exceed static array bound,
  1027  		// disable bounds check.
  1028  		if(n->bounded)
  1029  			goto ret;
  1030  		t = n->left->type;
  1031  		if(t != T && isptr[t->etype])
  1032  			t = t->type;
  1033  		if(isfixedarray(t)) {
  1034  			n->bounded = bounded(r, t->bound);
  1035  			if(debug['m'] && n->bounded && !isconst(n->right, CTINT))
  1036  				warn("index bounds check elided");
  1037  			if(smallintconst(n->right) && !n->bounded)
  1038  				yyerror("index out of bounds");
  1039  		} else if(isconst(n->left, CTSTR)) {
  1040  			n->bounded = bounded(r, n->left->val.u.sval->len);
  1041  			if(debug['m'] && n->bounded && !isconst(n->right, CTINT))
  1042  				warn("index bounds check elided");
  1043  			if(smallintconst(n->right)) {
  1044  				if(!n->bounded)
  1045  					yyerror("index out of bounds");
  1046  				else {
  1047  					// replace "abc"[1] with 'b'.
  1048  					// delayed until now because "abc"[1] is not
  1049  					// an ideal constant.
  1050  					v = mpgetfix(n->right->val.u.xval);
  1051  					nodconst(n, n->type, n->left->val.u.sval->s[v]);
  1052  					n->typecheck = 1;
  1053  				}
  1054  			}
  1055  		}
  1056  
  1057  		if(isconst(n->right, CTINT))
  1058  		if(mpcmpfixfix(n->right->val.u.xval, &mpzero) < 0 ||
  1059  		   mpcmpfixfix(n->right->val.u.xval, maxintval[TINT]) > 0)
  1060  			yyerror("index out of bounds");
  1061  		goto ret;
  1062  
  1063  	case OINDEXMAP:
  1064  		if(n->etype == 1)
  1065  			goto ret;
  1066  
  1067  		t = n->left->type;
  1068  		p = nil;
  1069  		if(t->type->width <= 128) {  // Check ../../pkg/runtime/hashmap.c:MAXVALUESIZE before changing.
  1070  			switch(simsimtype(t->down)) {
  1071  			case TINT32:
  1072  			case TUINT32:
  1073  				p = "mapaccess1_fast32";
  1074  				break;
  1075  			case TINT64:
  1076  			case TUINT64:
  1077  				p = "mapaccess1_fast64";
  1078  				break;
  1079  			case TSTRING:
  1080  				p = "mapaccess1_faststr";
  1081  				break;
  1082  			}
  1083  		}
  1084  		if(p != nil) {
  1085  			// use fast version.  The fast versions return a pointer to the value - we need
  1086  			// to dereference it to get the result.
  1087  			n = mkcall1(mapfn(p, t), ptrto(t->type), init, typename(t), n->left, n->right);
  1088  			n = nod(OIND, n, N);
  1089  			n->type = t->type;
  1090  			n->typecheck = 1;
  1091  		} else {
  1092  			// no fast version for this key
  1093  			n = mkcall1(mapfn("mapaccess1", t), t->type, init, typename(t), n->left, n->right);
  1094  		}
  1095  		goto ret;
  1096  
  1097  	case ORECV:
  1098  		walkexpr(&n->left, init);
  1099  		walkexpr(&n->right, init);
  1100  		n = mkcall1(chanfn("chanrecv1", 2, n->left->type), n->type, init, typename(n->left->type), n->left);
  1101  		goto ret;
  1102  
  1103  	case OSLICE:
  1104  		if(n->right != N && n->right->left == N && n->right->right == N) { // noop
  1105  			walkexpr(&n->left, init);
  1106  			n = n->left;
  1107  			goto ret;
  1108  		}
  1109  		// fallthrough
  1110  	case OSLICEARR:
  1111  	case OSLICESTR:
  1112  		if(n->right == N) // already processed
  1113  			goto ret;
  1114  
  1115  		walkexpr(&n->left, init);
  1116  		// cgen_slice can't handle string literals as source
  1117  		// TODO the OINDEX case is a bug elsewhere that needs to be traced.  it causes a crash on ([2][]int{ ... })[1][lo:hi]
  1118  		if((n->op == OSLICESTR && n->left->op == OLITERAL) || (n->left->op == OINDEX))
  1119  			n->left = copyexpr(n->left, n->left->type, init);
  1120  		else
  1121  			n->left = safeexpr(n->left, init);
  1122  		walkexpr(&n->right->left, init);
  1123  		n->right->left = safeexpr(n->right->left, init);
  1124  		walkexpr(&n->right->right, init);
  1125  		n->right->right = safeexpr(n->right->right, init);
  1126  		n = sliceany(n, init);  // chops n->right, sets n->list
  1127  		goto ret;
  1128  	
  1129  	case OSLICE3:
  1130  	case OSLICE3ARR:
  1131  		if(n->right == N) // already processed
  1132  			goto ret;
  1133  
  1134  		walkexpr(&n->left, init);
  1135  		// TODO the OINDEX case is a bug elsewhere that needs to be traced.  it causes a crash on ([2][]int{ ... })[1][lo:hi]
  1136  		// TODO the comment on the previous line was copied from case OSLICE. it might not even be true.
  1137  		if(n->left->op == OINDEX)
  1138  			n->left = copyexpr(n->left, n->left->type, init);
  1139  		else
  1140  			n->left = safeexpr(n->left, init);
  1141  		walkexpr(&n->right->left, init);
  1142  		n->right->left = safeexpr(n->right->left, init);
  1143  		walkexpr(&n->right->right->left, init);
  1144  		n->right->right->left = safeexpr(n->right->right->left, init);
  1145  		walkexpr(&n->right->right->right, init);
  1146  		n->right->right->right = safeexpr(n->right->right->right, init);
  1147  		n = sliceany(n, init);  // chops n->right, sets n->list
  1148  		goto ret;
  1149  
  1150  	case OADDR:
  1151  		walkexpr(&n->left, init);
  1152  		goto ret;
  1153  
  1154  	case ONEW:
  1155  		if(n->esc == EscNone && n->type->type->width < (1<<16)) {
  1156  			r = temp(n->type->type);
  1157  			r = nod(OAS, r, N);  // zero temp
  1158  			typecheck(&r, Etop);
  1159  			*init = list(*init, r);
  1160  			r = nod(OADDR, r->left, N);
  1161  			typecheck(&r, Erv);
  1162  			n = r;
  1163  		} else {
  1164  			n = callnew(n->type->type);
  1165  		}
  1166  		goto ret;
  1167  
  1168  	case OCMPSTR:
  1169  		// If one argument to the comparison is an empty string,
  1170  		// comparing the lengths instead will yield the same result
  1171  		// without the function call.
  1172  		if((isconst(n->left, CTSTR) && n->left->val.u.sval->len == 0) ||
  1173  		   (isconst(n->right, CTSTR) && n->right->val.u.sval->len == 0)) {
  1174  			r = nod(n->etype, nod(OLEN, n->left, N), nod(OLEN, n->right, N));
  1175  			typecheck(&r, Erv);
  1176  			walkexpr(&r, init);
  1177  			r->type = n->type;
  1178  			n = r;
  1179  			goto ret;
  1180  		}
  1181  
  1182  		// s + "badgerbadgerbadger" == "badgerbadgerbadger"
  1183  		if((n->etype == OEQ || n->etype == ONE) &&
  1184  		   isconst(n->right, CTSTR) &&
  1185  		   n->left->op == OADDSTR && isconst(n->left->right, CTSTR) &&
  1186  		   cmpslit(n->right, n->left->right) == 0) {
  1187  			r = nod(n->etype, nod(OLEN, n->left->left, N), nodintconst(0));
  1188  			typecheck(&r, Erv);
  1189  			walkexpr(&r, init);
  1190  			r->type = n->type;
  1191  			n = r;
  1192  			goto ret;
  1193  		}
  1194  
  1195  		if(n->etype == OEQ || n->etype == ONE) {
  1196  			// prepare for rewrite below
  1197  			n->left = cheapexpr(n->left, init);
  1198  			n->right = cheapexpr(n->right, init);
  1199  
  1200  			r = mkcall("eqstring", types[TBOOL], init,
  1201  				conv(n->left, types[TSTRING]),
  1202  				conv(n->right, types[TSTRING]));
  1203  
  1204  			// quick check of len before full compare for == or !=
  1205  			if(n->etype == OEQ) {
  1206  				// len(left) == len(right) && eqstring(left, right)
  1207  				r = nod(OANDAND, nod(OEQ, nod(OLEN, n->left, N), nod(OLEN, n->right, N)), r);
  1208  			} else {
  1209  				// len(left) != len(right) || !eqstring(left, right)
  1210  				r = nod(ONOT, r, N);
  1211  				r = nod(OOROR, nod(ONE, nod(OLEN, n->left, N), nod(OLEN, n->right, N)), r);
  1212  			}
  1213  			typecheck(&r, Erv);
  1214  			walkexpr(&r, nil);
  1215  		} else {
  1216  			// sys_cmpstring(s1, s2) :: 0
  1217  			r = mkcall("cmpstring", types[TINT], init,
  1218  				conv(n->left, types[TSTRING]),
  1219  				conv(n->right, types[TSTRING]));
  1220  			r = nod(n->etype, r, nodintconst(0));
  1221  		}
  1222  
  1223  		typecheck(&r, Erv);
  1224  		if(n->type->etype != TBOOL) fatal("cmp %T", n->type);
  1225  		r->type = n->type;
  1226  		n = r;
  1227  		goto ret;
  1228  
  1229  	case OADDSTR:
  1230  		n = addstr(n, init);
  1231  		goto ret;
  1232  	
  1233  	case OAPPEND:
  1234  		if(n->isddd)
  1235  			n = appendslice(n, init); // also works for append(slice, string).
  1236  		else
  1237  			n = append(n, init);
  1238  		goto ret;
  1239  
  1240  	case OCOPY:
  1241  		if(flag_race) {
  1242  			if(n->right->type->etype == TSTRING)
  1243  				fn = syslook("slicestringcopy", 1);
  1244  			else
  1245  				fn = syslook("copy", 1);
  1246  			argtype(fn, n->left->type);
  1247  			argtype(fn, n->right->type);
  1248  			n = mkcall1(fn, n->type, init,
  1249  					n->left, n->right,
  1250  					nodintconst(n->left->type->type->width));
  1251  			goto ret;
  1252  		}
  1253  		n = copyany(n, init);
  1254  		goto ret;
  1255  
  1256  	case OCLOSE:
  1257  		// cannot use chanfn - closechan takes any, not chan any
  1258  		fn = syslook("closechan", 1);
  1259  		argtype(fn, n->left->type);
  1260  		n = mkcall1(fn, T, init, n->left);
  1261  		goto ret;
  1262  
  1263  	case OMAKECHAN:
  1264  		n = mkcall1(chanfn("makechan", 1, n->type), n->type, init,
  1265  			typename(n->type),
  1266  			conv(n->left, types[TINT64]));
  1267  		goto ret;
  1268  
  1269  	case OMAKEMAP:
  1270  		t = n->type;
  1271  
  1272  		fn = syslook("makemap", 1);
  1273  		argtype(fn, t->down);	// any-1
  1274  		argtype(fn, t->type);	// any-2
  1275  
  1276  		n = mkcall1(fn, n->type, init,
  1277  			typename(n->type),
  1278  			conv(n->left, types[TINT64]));
  1279  		goto ret;
  1280  
  1281  	case OMAKESLICE:
  1282  		l = n->left;
  1283  		r = n->right;
  1284  		if(r == nil)
  1285  			l = r = safeexpr(l, init);
  1286  		t = n->type;
  1287  		if(n->esc == EscNone
  1288  			&& smallintconst(l) && smallintconst(r)
  1289  			&& (t->type->width == 0 || mpgetfix(r->val.u.xval) < (1ULL<<16) / t->type->width)) {
  1290  			// var arr [r]T
  1291  			// n = arr[:l]
  1292  			t = aindex(r, t->type); // [r]T
  1293  			var = temp(t);
  1294  			a = nod(OAS, var, N); // zero temp
  1295  			typecheck(&a, Etop);
  1296  			*init = list(*init, a);
  1297  			r = nod(OSLICE, var, nod(OKEY, N, l)); // arr[:l]
  1298  			r = conv(r, n->type); // in case n->type is named.
  1299  			typecheck(&r, Erv);
  1300  			walkexpr(&r, init);
  1301  			n = r;
  1302  		} else {
  1303  			// makeslice(t *Type, nel int64, max int64) (ary []any)
  1304  			fn = syslook("makeslice", 1);
  1305  			argtype(fn, t->type);			// any-1
  1306  			n = mkcall1(fn, n->type, init,
  1307  				typename(n->type),
  1308  				conv(l, types[TINT64]),
  1309  				conv(r, types[TINT64]));
  1310  		}
  1311  		goto ret;
  1312  
  1313  	case ORUNESTR:
  1314  		// sys_intstring(v)
  1315  		n = mkcall("intstring", n->type, init,
  1316  			conv(n->left, types[TINT64]));
  1317  		goto ret;
  1318  
  1319  	case OARRAYBYTESTR:
  1320  		// slicebytetostring([]byte) string;
  1321  		n = mkcall("slicebytetostring", n->type, init, n->left);
  1322  		goto ret;
  1323  
  1324  	case OARRAYRUNESTR:
  1325  		// slicerunetostring([]rune) string;
  1326  		n = mkcall("slicerunetostring", n->type, init, n->left);
  1327  		goto ret;
  1328  
  1329  	case OSTRARRAYBYTE:
  1330  		// stringtoslicebyte(string) []byte;
  1331  		n = mkcall("stringtoslicebyte", n->type, init, conv(n->left, types[TSTRING]));
  1332  		goto ret;
  1333  
  1334  	case OSTRARRAYRUNE:
  1335  		// stringtoslicerune(string) []rune
  1336  		n = mkcall("stringtoslicerune", n->type, init, n->left);
  1337  		goto ret;
  1338  
  1339  	case OCMPIFACE:
  1340  		// ifaceeq(i1 any-1, i2 any-2) (ret bool);
  1341  		if(!eqtype(n->left->type, n->right->type))
  1342  			fatal("ifaceeq %O %T %T", n->op, n->left->type, n->right->type);
  1343  		if(isnilinter(n->left->type))
  1344  			fn = syslook("efaceeq", 1);
  1345  		else
  1346  			fn = syslook("ifaceeq", 1);
  1347  
  1348  		n->right = cheapexpr(n->right, init);
  1349  		n->left = cheapexpr(n->left, init);
  1350  		argtype(fn, n->right->type);
  1351  		argtype(fn, n->left->type);
  1352  		r = mkcall1(fn, n->type, init, n->left, n->right);
  1353  		if(n->etype == ONE)
  1354  			r = nod(ONOT, r, N);
  1355  		
  1356  		// check itable/type before full compare.
  1357  		if(n->etype == OEQ)
  1358  			r = nod(OANDAND, nod(OEQ, nod(OITAB, n->left, N), nod(OITAB, n->right, N)), r);
  1359  		else
  1360  			r = nod(OOROR, nod(ONE, nod(OITAB, n->left, N), nod(OITAB, n->right, N)), r);
  1361  		typecheck(&r, Erv);
  1362  		walkexpr(&r, init);
  1363  		r->type = n->type;
  1364  		n = r;
  1365  		goto ret;
  1366  
  1367  	case OARRAYLIT:
  1368  	case OMAPLIT:
  1369  	case OSTRUCTLIT:
  1370  	case OPTRLIT:
  1371  		var = temp(n->type);
  1372  		anylit(0, n, var, init);
  1373  		n = var;
  1374  		goto ret;
  1375  
  1376  	case OSEND:
  1377  		n = mkcall1(chanfn("chansend1", 2, n->left->type), T, init, typename(n->left->type), n->left, n->right);
  1378  		goto ret;
  1379  
  1380  	case OCLOSURE:
  1381  		n = walkclosure(n, init);
  1382  		goto ret;
  1383  	
  1384  	case OCALLPART:
  1385  		n = walkpartialcall(n, init);
  1386  		goto ret;
  1387  	}
  1388  	fatal("missing switch %O", n->op);
  1389  
  1390  ret:
  1391  	// Expressions that are constant at run time but not
  1392  	// considered const by the language spec are not turned into
  1393  	// constants until walk. For example, if n is y%1 == 0, the
  1394  	// walk of y%1 may have replaced it by 0.
  1395  	// Check whether n with its updated args is itself now a constant.
  1396  	t = n->type;
  1397  	evconst(n);
  1398  	n->type = t;
  1399  	if(n->op == OLITERAL)
  1400  		typecheck(&n, Erv);
  1401  
  1402  	ullmancalc(n);
  1403  
  1404  	if(debug['w'] && n != N)
  1405  		dump("walk", n);
  1406  
  1407  	lineno = lno;
  1408  	*np = n;
  1409  }
  1410  
  1411  static Node*
  1412  ascompatee1(int op, Node *l, Node *r, NodeList **init)
  1413  {
  1414  	Node *n;
  1415  	USED(op);
  1416  	
  1417  	// convas will turn map assigns into function calls,
  1418  	// making it impossible for reorder3 to work.
  1419  	n = nod(OAS, l, r);
  1420  	if(l->op == OINDEXMAP)
  1421  		return n;
  1422  
  1423  	return convas(n, init);
  1424  }
  1425  
  1426  static NodeList*
  1427  ascompatee(int op, NodeList *nl, NodeList *nr, NodeList **init)
  1428  {
  1429  	NodeList *ll, *lr, *nn;
  1430  
  1431  	/*
  1432  	 * check assign expression list to
  1433  	 * a expression list. called in
  1434  	 *	expr-list = expr-list
  1435  	 */
  1436  
  1437  	// ensure order of evaluation for function calls
  1438  	for(ll=nl; ll; ll=ll->next)
  1439  		ll->n = safeexpr(ll->n, init);
  1440  	for(lr=nr; lr; lr=lr->next)
  1441  		lr->n = safeexpr(lr->n, init);
  1442  
  1443  	nn = nil;
  1444  	for(ll=nl, lr=nr; ll && lr; ll=ll->next, lr=lr->next) {
  1445  		// Do not generate 'x = x' during return. See issue 4014.
  1446  		if(op == ORETURN && ll->n == lr->n)
  1447  			continue;
  1448  		nn = list(nn, ascompatee1(op, ll->n, lr->n, init));
  1449  	}
  1450  
  1451  	// cannot happen: caller checked that lists had same length
  1452  	if(ll || lr)
  1453  		yyerror("error in shape across %+H %O %+H / %d %d [%s]", nl, op, nr, count(nl), count(nr), curfn->nname->sym->name);
  1454  	return nn;
  1455  }
  1456  
  1457  /*
  1458   * l is an lv and rt is the type of an rv
  1459   * return 1 if this implies a function call
  1460   * evaluating the lv or a function call
  1461   * in the conversion of the types
  1462   */
  1463  static int
  1464  fncall(Node *l, Type *rt)
  1465  {
  1466  	if(l->ullman >= UINF || l->op == OINDEXMAP)
  1467  		return 1;
  1468  	if(eqtype(l->type, rt))
  1469  		return 0;
  1470  	return 1;
  1471  }
  1472  
  1473  static NodeList*
  1474  ascompatet(int op, NodeList *nl, Type **nr, int fp, NodeList **init)
  1475  {
  1476  	Node *l, *tmp, *a;
  1477  	NodeList *ll;
  1478  	Type *r;
  1479  	Iter saver;
  1480  	int ucount;
  1481  	NodeList *nn, *mm;
  1482  
  1483  	USED(op);
  1484  
  1485  	/*
  1486  	 * check assign type list to
  1487  	 * a expression list. called in
  1488  	 *	expr-list = func()
  1489  	 */
  1490  	r = structfirst(&saver, nr);
  1491  	nn = nil;
  1492  	mm = nil;
  1493  	ucount = 0;
  1494  	for(ll=nl; ll; ll=ll->next) {
  1495  		if(r == T)
  1496  			break;
  1497  		l = ll->n;
  1498  		if(isblank(l)) {
  1499  			r = structnext(&saver);
  1500  			continue;
  1501  		}
  1502  
  1503  		// any lv that causes a fn call must be
  1504  		// deferred until all the return arguments
  1505  		// have been pulled from the output arguments
  1506  		if(fncall(l, r->type)) {
  1507  			tmp = temp(r->type);
  1508  			typecheck(&tmp, Erv);
  1509  			a = nod(OAS, l, tmp);
  1510  			a = convas(a, init);
  1511  			mm = list(mm, a);
  1512  			l = tmp;
  1513  		}
  1514  
  1515  		a = nod(OAS, l, nodarg(r, fp));
  1516  		a = convas(a, init);
  1517  		ullmancalc(a);
  1518  		if(a->ullman >= UINF)
  1519  			ucount++;
  1520  		nn = list(nn, a);
  1521  		r = structnext(&saver);
  1522  	}
  1523  
  1524  	if(ll != nil || r != T)
  1525  		yyerror("ascompatet: assignment count mismatch: %d = %d",
  1526  			count(nl), structcount(*nr));
  1527  
  1528  	if(ucount)
  1529  		fatal("ascompatet: too many function calls evaluating parameters");
  1530  	return concat(nn, mm);
  1531  }
  1532  
  1533   /*
  1534   * package all the arguments that match a ... T parameter into a []T.
  1535   */
  1536  static NodeList*
  1537  mkdotargslice(NodeList *lr0, NodeList *nn, Type *l, int fp, NodeList **init, int esc)
  1538  {
  1539  	Node *a, *n;
  1540  	Type *tslice;
  1541  
  1542  	tslice = typ(TARRAY);
  1543  	tslice->type = l->type->type;
  1544  	tslice->bound = -1;
  1545  
  1546  	if(count(lr0) == 0) {
  1547  		n = nodnil();
  1548  		n->type = tslice;
  1549  	} else {
  1550  		n = nod(OCOMPLIT, N, typenod(tslice));
  1551  		n->list = lr0;
  1552  		n->esc = esc;
  1553  		typecheck(&n, Erv);
  1554  		if(n->type == T)
  1555  			fatal("mkdotargslice: typecheck failed");
  1556  		walkexpr(&n, init);
  1557  	}
  1558  
  1559  	a = nod(OAS, nodarg(l, fp), n);
  1560  	nn = list(nn, convas(a, init));
  1561  	return nn;
  1562  }
  1563  
  1564  /*
  1565   * helpers for shape errors
  1566   */
  1567  static char*
  1568  dumptypes(Type **nl, char *what)
  1569  {
  1570  	int first;
  1571  	Type *l;
  1572  	Iter savel;
  1573  	Fmt fmt;
  1574  
  1575  	fmtstrinit(&fmt);
  1576  	fmtprint(&fmt, "\t");
  1577  	first = 1;
  1578  	for(l = structfirst(&savel, nl); l != T; l = structnext(&savel)) {
  1579  		if(first)
  1580  			first = 0;
  1581  		else
  1582  			fmtprint(&fmt, ", ");
  1583  		fmtprint(&fmt, "%T", l);
  1584  	}
  1585  	if(first)
  1586  		fmtprint(&fmt, "[no arguments %s]", what);
  1587  	return fmtstrflush(&fmt);
  1588  }
  1589  
  1590  static char*
  1591  dumpnodetypes(NodeList *l, char *what)
  1592  {
  1593  	int first;
  1594  	Node *r;
  1595  	Fmt fmt;
  1596  
  1597  	fmtstrinit(&fmt);
  1598  	fmtprint(&fmt, "\t");
  1599  	first = 1;
  1600  	for(; l; l=l->next) {
  1601  		r = l->n;
  1602  		if(first)
  1603  			first = 0;
  1604  		else
  1605  			fmtprint(&fmt, ", ");
  1606  		fmtprint(&fmt, "%T", r->type);
  1607  	}
  1608  	if(first)
  1609  		fmtprint(&fmt, "[no arguments %s]", what);
  1610  	return fmtstrflush(&fmt);
  1611  }
  1612  
  1613  /*
  1614   * check assign expression list to
  1615   * a type list. called in
  1616   *	return expr-list
  1617   *	func(expr-list)
  1618   */
  1619  static NodeList*
  1620  ascompatte(int op, Node *call, int isddd, Type **nl, NodeList *lr, int fp, NodeList **init)
  1621  {
  1622  	int esc;
  1623  	Type *l, *ll;
  1624  	Node *r, *a;
  1625  	NodeList *nn, *lr0, *alist;
  1626  	Iter savel;
  1627  	char *l1, *l2;
  1628  
  1629  	lr0 = lr;
  1630  	l = structfirst(&savel, nl);
  1631  	r = N;
  1632  	if(lr)
  1633  		r = lr->n;
  1634  	nn = nil;
  1635  
  1636  	// f(g()) where g has multiple return values
  1637  	if(r != N && lr->next == nil && r->type->etype == TSTRUCT && r->type->funarg) {
  1638  		// optimization - can do block copy
  1639  		if(eqtypenoname(r->type, *nl)) {
  1640  			a = nodarg(*nl, fp);
  1641  			a->type = r->type;
  1642  			nn = list1(convas(nod(OAS, a, r), init));
  1643  			goto ret;
  1644  		}
  1645  
  1646  		// conversions involved.
  1647  		// copy into temporaries.
  1648  		alist = nil;
  1649  		for(l=structfirst(&savel, &r->type); l; l=structnext(&savel)) {
  1650  			a = temp(l->type);
  1651  			alist = list(alist, a);
  1652  		}
  1653  		a = nod(OAS2, N, N);
  1654  		a->list = alist;
  1655  		a->rlist = lr;
  1656  		typecheck(&a, Etop);
  1657  		walkstmt(&a);
  1658  		*init = list(*init, a);
  1659  		lr = alist;
  1660  		r = lr->n;
  1661  		l = structfirst(&savel, nl);
  1662  	}
  1663  
  1664  loop:
  1665  	if(l != T && l->isddd) {
  1666  		// the ddd parameter must be last
  1667  		ll = structnext(&savel);
  1668  		if(ll != T)
  1669  			yyerror("... must be last argument");
  1670  
  1671  		// special case --
  1672  		// only if we are assigning a single ddd
  1673  		// argument to a ddd parameter then it is
  1674  		// passed thru unencapsulated
  1675  		if(r != N && lr->next == nil && isddd && eqtype(l->type, r->type)) {
  1676  			a = nod(OAS, nodarg(l, fp), r);
  1677  			a = convas(a, init);
  1678  			nn = list(nn, a);
  1679  			goto ret;
  1680  		}
  1681  
  1682  		// normal case -- make a slice of all
  1683  		// remaining arguments and pass it to
  1684  		// the ddd parameter.
  1685  		esc = EscUnknown;
  1686  		if(call->right)
  1687  			esc = call->right->esc;
  1688  		nn = mkdotargslice(lr, nn, l, fp, init, esc);
  1689  		goto ret;
  1690  	}
  1691  
  1692  	if(l == T || r == N) {
  1693  		if(l != T || r != N) {
  1694  			l1 = dumptypes(nl, "expected");
  1695  			l2 = dumpnodetypes(lr0, "given");
  1696  			if(l != T)
  1697  				yyerror("not enough arguments to %O\n%s\n%s", op, l1, l2);
  1698  			else
  1699  				yyerror("too many arguments to %O\n%s\n%s", op, l1, l2);
  1700  		}
  1701  		goto ret;
  1702  	}
  1703  
  1704  	a = nod(OAS, nodarg(l, fp), r);
  1705  	a = convas(a, init);
  1706  	nn = list(nn, a);
  1707  
  1708  	l = structnext(&savel);
  1709  	r = N;
  1710  	lr = lr->next;
  1711  	if(lr != nil)
  1712  		r = lr->n;
  1713  	goto loop;
  1714  
  1715  ret:
  1716  	for(lr=nn; lr; lr=lr->next)
  1717  		lr->n->typecheck = 1;
  1718  	return nn;
  1719  }
  1720  
  1721  // generate code for print
  1722  static Node*
  1723  walkprint(Node *nn, NodeList **init, int defer)
  1724  {
  1725  	Node *r;
  1726  	Node *n;
  1727  	NodeList *l, *all;
  1728  	Node *on;
  1729  	Type *t;
  1730  	int notfirst, et, op;
  1731  	NodeList *calls, *intypes, *args;
  1732  	Fmt fmt;
  1733  
  1734  	on = nil;
  1735  	op = nn->op;
  1736  	all = nn->list;
  1737  	calls = nil;
  1738  	notfirst = 0;
  1739  	intypes = nil;
  1740  	args = nil;
  1741  
  1742  	memset(&fmt, 0, sizeof fmt);
  1743  	if(defer) {
  1744  		// defer print turns into defer printf with format string
  1745  		fmtstrinit(&fmt);
  1746  		intypes = list(intypes, nod(ODCLFIELD, N, typenod(types[TSTRING])));
  1747  		args = list1(nod(OXXX, N, N));
  1748  	}
  1749  
  1750  	for(l=all; l; l=l->next) {
  1751  		if(notfirst) {
  1752  			if(defer)
  1753  				fmtprint(&fmt, " ");
  1754  			else
  1755  				calls = list(calls, mkcall("printsp", T, init));
  1756  		}
  1757  		notfirst = op == OPRINTN;
  1758  
  1759  		n = l->n;
  1760  		if(n->op == OLITERAL) {
  1761  			switch(n->val.ctype) {
  1762  			case CTRUNE:
  1763  				defaultlit(&n, runetype);
  1764  				break;
  1765  			case CTINT:
  1766  				defaultlit(&n, types[TINT64]);
  1767  				break;
  1768  			case CTFLT:
  1769  				defaultlit(&n, types[TFLOAT64]);
  1770  				break;
  1771  			}
  1772  		}
  1773  		if(n->op != OLITERAL && n->type && n->type->etype == TIDEAL)
  1774  			defaultlit(&n, types[TINT64]);
  1775  		defaultlit(&n, nil);
  1776  		l->n = n;
  1777  		if(n->type == T || n->type->etype == TFORW)
  1778  			continue;
  1779  
  1780  		t = n->type;
  1781  		et = n->type->etype;
  1782  		if(isinter(n->type)) {
  1783  			if(defer) {
  1784  				if(isnilinter(n->type))
  1785  					fmtprint(&fmt, "%%e");
  1786  				else
  1787  					fmtprint(&fmt, "%%i");
  1788  			} else {
  1789  				if(isnilinter(n->type))
  1790  					on = syslook("printeface", 1);
  1791  				else
  1792  					on = syslook("printiface", 1);
  1793  				argtype(on, n->type);		// any-1
  1794  			}
  1795  		} else if(isptr[et] || et == TCHAN || et == TMAP || et == TFUNC || et == TUNSAFEPTR) {
  1796  			if(defer) {
  1797  				fmtprint(&fmt, "%%p");
  1798  			} else {
  1799  				on = syslook("printpointer", 1);
  1800  				argtype(on, n->type);	// any-1
  1801  			}
  1802  		} else if(isslice(n->type)) {
  1803  			if(defer) {
  1804  				fmtprint(&fmt, "%%a");
  1805  			} else {
  1806  				on = syslook("printslice", 1);
  1807  				argtype(on, n->type);	// any-1
  1808  			}
  1809  		} else if(isint[et]) {
  1810  			if(defer) {
  1811  				if(et == TUINT64)
  1812  					fmtprint(&fmt, "%%U");
  1813  				else {
  1814  					fmtprint(&fmt, "%%D");
  1815  					t = types[TINT64];
  1816  				}
  1817  			} else {
  1818  				if(et == TUINT64)
  1819  					on = syslook("printuint", 0);
  1820  				else
  1821  					on = syslook("printint", 0);
  1822  			}
  1823  		} else if(isfloat[et]) {
  1824  			if(defer) {
  1825  				fmtprint(&fmt, "%%f");
  1826  				t = types[TFLOAT64];
  1827  			} else
  1828  				on = syslook("printfloat", 0);
  1829  		} else if(iscomplex[et]) {
  1830  			if(defer) {
  1831  				fmtprint(&fmt, "%%C");
  1832  				t = types[TCOMPLEX128];
  1833  			} else
  1834  				on = syslook("printcomplex", 0);
  1835  		} else if(et == TBOOL) {
  1836  			if(defer)
  1837  				fmtprint(&fmt, "%%t");
  1838  			else
  1839  				on = syslook("printbool", 0);
  1840  		} else if(et == TSTRING) {
  1841  			if(defer)
  1842  				fmtprint(&fmt, "%%S");
  1843  			else
  1844  				on = syslook("printstring", 0);
  1845  		} else {
  1846  			badtype(OPRINT, n->type, T);
  1847  			continue;
  1848  		}
  1849  
  1850  		if(!defer) {
  1851  			t = *getinarg(on->type);
  1852  			if(t != nil)
  1853  				t = t->type;
  1854  			if(t != nil)
  1855  				t = t->type;
  1856  		}
  1857  
  1858  		if(!eqtype(t, n->type)) {
  1859  			n = nod(OCONV, n, N);
  1860  			n->type = t;
  1861  		}
  1862  
  1863  		if(defer) {
  1864  			intypes = list(intypes, nod(ODCLFIELD, N, typenod(t)));
  1865  			args = list(args, n);
  1866  		} else {
  1867  			r = nod(OCALL, on, N);
  1868  			r->list = list1(n);
  1869  			calls = list(calls, r);
  1870  		}
  1871  	}
  1872  
  1873  	if(defer) {
  1874  		if(op == OPRINTN)
  1875  			fmtprint(&fmt, "\n");
  1876  		on = syslook("goprintf", 1);
  1877  		on->type = functype(nil, intypes, nil);
  1878  		args->n = nod(OLITERAL, N, N);
  1879  		args->n->val.ctype = CTSTR;
  1880  		args->n->val.u.sval = strlit(fmtstrflush(&fmt));
  1881  		r = nod(OCALL, on, N);
  1882  		r->list = args;
  1883  		typecheck(&r, Etop);
  1884  		walkexpr(&r, init);
  1885  	} else {
  1886  		if(op == OPRINTN)
  1887  			calls = list(calls, mkcall("printnl", T, nil));
  1888  		typechecklist(calls, Etop);
  1889  		walkexprlist(calls, init);
  1890  
  1891  		r = nod(OEMPTY, N, N);
  1892  		typecheck(&r, Etop);
  1893  		walkexpr(&r, init);
  1894  		r->ninit = calls;
  1895  	}
  1896  	return r;
  1897  }
  1898  
  1899  Node*
  1900  callnew(Type *t)
  1901  {
  1902  	Node *fn;
  1903  
  1904  	dowidth(t);
  1905  	fn = syslook("new", 1);
  1906  	argtype(fn, t);
  1907  	return mkcall1(fn, ptrto(t), nil, typename(t));
  1908  }
  1909  
  1910  static Node*
  1911  convas(Node *n, NodeList **init)
  1912  {
  1913  	Type *lt, *rt;
  1914  
  1915  	if(n->op != OAS)
  1916  		fatal("convas: not OAS %O", n->op);
  1917  
  1918  	n->typecheck = 1;
  1919  
  1920  	if(n->left == N || n->right == N)
  1921  		goto out;
  1922  
  1923  	lt = n->left->type;
  1924  	rt = n->right->type;
  1925  	if(lt == T || rt == T)
  1926  		goto out;
  1927  
  1928  	if(isblank(n->left)) {
  1929  		defaultlit(&n->right, T);
  1930  		goto out;
  1931  	}
  1932  
  1933  	if(n->left->op == OINDEXMAP) {
  1934  		n = mkcall1(mapfn("mapassign1", n->left->left->type), T, init,
  1935  			typename(n->left->left->type),
  1936  			n->left->left, n->left->right, n->right);
  1937  		goto out;
  1938  	}
  1939  
  1940  	if(eqtype(lt, rt))
  1941  		goto out;
  1942  
  1943  	n->right = assignconv(n->right, lt, "assignment");
  1944  	walkexpr(&n->right, init);
  1945  
  1946  out:
  1947  	ullmancalc(n);
  1948  	return n;
  1949  }
  1950  
  1951  /*
  1952   * from ascompat[te]
  1953   * evaluating actual function arguments.
  1954   *	f(a,b)
  1955   * if there is exactly one function expr,
  1956   * then it is done first. otherwise must
  1957   * make temp variables
  1958   */
  1959  static NodeList*
  1960  reorder1(NodeList *all)
  1961  {
  1962  	Node *f, *a, *n;
  1963  	NodeList *l, *r, *g;
  1964  	int c, d, t;
  1965  
  1966  	c = 0;	// function calls
  1967  	t = 0;	// total parameters
  1968  
  1969  	for(l=all; l; l=l->next) {
  1970  		n = l->n;
  1971  		t++;
  1972  		ullmancalc(n);
  1973  		if(n->ullman >= UINF)
  1974  			c++;
  1975  	}
  1976  	if(c == 0 || t == 1)
  1977  		return all;
  1978  
  1979  	g = nil;	// fncalls assigned to tempnames
  1980  	f = N;	// last fncall assigned to stack
  1981  	r = nil;	// non fncalls and tempnames assigned to stack
  1982  	d = 0;
  1983  	for(l=all; l; l=l->next) {
  1984  		n = l->n;
  1985  		if(n->ullman < UINF) {
  1986  			r = list(r, n);
  1987  			continue;
  1988  		}
  1989  		d++;
  1990  		if(d == c) {
  1991  			f = n;
  1992  			continue;
  1993  		}
  1994  
  1995  		// make assignment of fncall to tempname
  1996  		a = temp(n->right->type);
  1997  		a = nod(OAS, a, n->right);
  1998  		g = list(g, a);
  1999  
  2000  		// put normal arg assignment on list
  2001  		// with fncall replaced by tempname
  2002  		n->right = a->left;
  2003  		r = list(r, n);
  2004  	}
  2005  
  2006  	if(f != N)
  2007  		g = list(g, f);
  2008  	return concat(g, r);
  2009  }
  2010  
  2011  static void reorder3save(Node**, NodeList*, NodeList*, NodeList**);
  2012  static int aliased(Node*, NodeList*, NodeList*);
  2013  
  2014  /*
  2015   * from ascompat[ee]
  2016   *	a,b = c,d
  2017   * simultaneous assignment. there cannot
  2018   * be later use of an earlier lvalue.
  2019   *
  2020   * function calls have been removed.
  2021   */
  2022  static NodeList*
  2023  reorder3(NodeList *all)
  2024  {
  2025  	NodeList *list, *early, *mapinit;
  2026  	Node *l;
  2027  
  2028  	// If a needed expression may be affected by an
  2029  	// earlier assignment, make an early copy of that
  2030  	// expression and use the copy instead.
  2031  	early = nil;
  2032  	mapinit = nil;
  2033  	for(list=all; list; list=list->next) {
  2034  		l = list->n->left;
  2035  
  2036  		// Save subexpressions needed on left side.
  2037  		// Drill through non-dereferences.
  2038  		for(;;) {
  2039  			if(l->op == ODOT || l->op == OPAREN) {
  2040  				l = l->left;
  2041  				continue;
  2042  			}
  2043  			if(l->op == OINDEX && isfixedarray(l->left->type)) {
  2044  				reorder3save(&l->right, all, list, &early);
  2045  				l = l->left;
  2046  				continue;
  2047  			}
  2048  			break;
  2049  		}
  2050  		switch(l->op) {
  2051  		default:
  2052  			fatal("reorder3 unexpected lvalue %#O", l->op);
  2053  		case ONAME:
  2054  			break;
  2055  		case OINDEX:
  2056  		case OINDEXMAP:
  2057  			reorder3save(&l->left, all, list, &early);
  2058  			reorder3save(&l->right, all, list, &early);
  2059  			if(l->op == OINDEXMAP)
  2060  				list->n = convas(list->n, &mapinit);
  2061  			break;
  2062  		case OIND:
  2063  		case ODOTPTR:
  2064  			reorder3save(&l->left, all, list, &early);
  2065  		}
  2066  
  2067  		// Save expression on right side.
  2068  		reorder3save(&list->n->right, all, list, &early);
  2069  	}
  2070  
  2071  	early = concat(mapinit, early);
  2072  	return concat(early, all);
  2073  }
  2074  
  2075  static int vmatch2(Node*, Node*);
  2076  static int varexpr(Node*);
  2077  
  2078  /*
  2079   * if the evaluation of *np would be affected by the 
  2080   * assignments in all up to but not including stop,
  2081   * copy into a temporary during *early and
  2082   * replace *np with that temp.
  2083   */
  2084  static void
  2085  reorder3save(Node **np, NodeList *all, NodeList *stop, NodeList **early)
  2086  {
  2087  	Node *n, *q;
  2088  
  2089  	n = *np;
  2090  	if(!aliased(n, all, stop))
  2091  		return;
  2092  	
  2093  	q = temp(n->type);
  2094  	q = nod(OAS, q, n);
  2095  	typecheck(&q, Etop);
  2096  	*early = list(*early, q);
  2097  	*np = q->left;
  2098  }
  2099  
  2100  /*
  2101   * what's the outer value that a write to n affects?
  2102   * outer value means containing struct or array.
  2103   */
  2104  static Node*
  2105  outervalue(Node *n)
  2106  {	
  2107  	for(;;) {
  2108  		if(n->op == ODOT || n->op == OPAREN) {
  2109  			n = n->left;
  2110  			continue;
  2111  		}
  2112  		if(n->op == OINDEX && isfixedarray(n->left->type)) {
  2113  			n = n->left;
  2114  			continue;
  2115  		}
  2116  		break;
  2117  	}
  2118  	return n;
  2119  }
  2120  
  2121  /*
  2122   * Is it possible that the computation of n might be
  2123   * affected by writes in as up to but not including stop?
  2124   */
  2125  static int
  2126  aliased(Node *n, NodeList *all, NodeList *stop)
  2127  {
  2128  	int memwrite, varwrite;
  2129  	Node *a;
  2130  	NodeList *l;
  2131  
  2132  	if(n == N)
  2133  		return 0;
  2134  
  2135  	// Look for obvious aliasing: a variable being assigned
  2136  	// during the all list and appearing in n.
  2137  	// Also record whether there are any writes to main memory.
  2138  	// Also record whether there are any writes to variables
  2139  	// whose addresses have been taken.
  2140  	memwrite = 0;
  2141  	varwrite = 0;
  2142  	for(l=all; l!=stop; l=l->next) {
  2143  		a = outervalue(l->n->left);
  2144  		if(a->op != ONAME) {
  2145  			memwrite = 1;
  2146  			continue;
  2147  		}
  2148  		switch(n->class) {
  2149  		default:
  2150  			varwrite = 1;
  2151  			continue;
  2152  		case PAUTO:
  2153  		case PPARAM:
  2154  		case PPARAMOUT:
  2155  			if(n->addrtaken) {
  2156  				varwrite = 1;
  2157  				continue;
  2158  			}
  2159  			if(vmatch2(a, n)) {
  2160  				// Direct hit.
  2161  				return 1;
  2162  			}
  2163  		}
  2164  	}
  2165  
  2166  	// The variables being written do not appear in n.
  2167  	// However, n might refer to computed addresses
  2168  	// that are being written.
  2169  	
  2170  	// If no computed addresses are affected by the writes, no aliasing.
  2171  	if(!memwrite && !varwrite)
  2172  		return 0;
  2173  
  2174  	// If n does not refer to computed addresses
  2175  	// (that is, if n only refers to variables whose addresses
  2176  	// have not been taken), no aliasing.
  2177  	if(varexpr(n))
  2178  		return 0;
  2179  
  2180  	// Otherwise, both the writes and n refer to computed memory addresses.
  2181  	// Assume that they might conflict.
  2182  	return 1;
  2183  }
  2184  
  2185  /*
  2186   * does the evaluation of n only refer to variables
  2187   * whose addresses have not been taken?
  2188   * (and no other memory)
  2189   */
  2190  static int
  2191  varexpr(Node *n)
  2192  {
  2193  	if(n == N)
  2194  		return 1;
  2195  
  2196  	switch(n->op) {
  2197  	case OLITERAL:	
  2198  		return 1;
  2199  	case ONAME:
  2200  		switch(n->class) {
  2201  		case PAUTO:
  2202  		case PPARAM:
  2203  		case PPARAMOUT:
  2204  			if(!n->addrtaken)
  2205  				return 1;
  2206  		}
  2207  		return 0;
  2208  
  2209  	case OADD:
  2210  	case OSUB:
  2211  	case OOR:
  2212  	case OXOR:
  2213  	case OMUL:
  2214  	case ODIV:
  2215  	case OMOD:
  2216  	case OLSH:
  2217  	case ORSH:
  2218  	case OAND:
  2219  	case OANDNOT:
  2220  	case OPLUS:
  2221  	case OMINUS:
  2222  	case OCOM:
  2223  	case OPAREN:
  2224  	case OANDAND:
  2225  	case OOROR:
  2226  	case ODOT:  // but not ODOTPTR
  2227  	case OCONV:
  2228  	case OCONVNOP:
  2229  	case OCONVIFACE:
  2230  	case ODOTTYPE:
  2231  		return varexpr(n->left) && varexpr(n->right);
  2232  	}
  2233  
  2234  	// Be conservative.
  2235  	return 0;
  2236  }
  2237  
  2238  /*
  2239   * is the name l mentioned in r?
  2240   */
  2241  static int
  2242  vmatch2(Node *l, Node *r)
  2243  {
  2244  	NodeList *ll;
  2245  
  2246  	if(r == N)
  2247  		return 0;
  2248  	switch(r->op) {
  2249  	case ONAME:
  2250  		// match each right given left
  2251  		return l == r;
  2252  	case OLITERAL:
  2253  		return 0;
  2254  	}
  2255  	if(vmatch2(l, r->left))
  2256  		return 1;
  2257  	if(vmatch2(l, r->right))
  2258  		return 1;
  2259  	for(ll=r->list; ll; ll=ll->next)
  2260  		if(vmatch2(l, ll->n))
  2261  			return 1;
  2262  	return 0;
  2263  }
  2264  
  2265  /*
  2266   * is any name mentioned in l also mentioned in r?
  2267   * called by sinit.c
  2268   */
  2269  int
  2270  vmatch1(Node *l, Node *r)
  2271  {
  2272  	NodeList *ll;
  2273  
  2274  	/*
  2275  	 * isolate all left sides
  2276  	 */
  2277  	if(l == N || r == N)
  2278  		return 0;
  2279  	switch(l->op) {
  2280  	case ONAME:
  2281  		switch(l->class) {
  2282  		case PPARAM:
  2283  		case PPARAMREF:
  2284  		case PAUTO:
  2285  			break;
  2286  		default:
  2287  			// assignment to non-stack variable
  2288  			// must be delayed if right has function calls.
  2289  			if(r->ullman >= UINF)
  2290  				return 1;
  2291  			break;
  2292  		}
  2293  		return vmatch2(l, r);
  2294  	case OLITERAL:
  2295  		return 0;
  2296  	}
  2297  	if(vmatch1(l->left, r))
  2298  		return 1;
  2299  	if(vmatch1(l->right, r))
  2300  		return 1;
  2301  	for(ll=l->list; ll; ll=ll->next)
  2302  		if(vmatch1(ll->n, r))
  2303  			return 1;
  2304  	return 0;
  2305  }
  2306  
  2307  /*
  2308   * walk through argin parameters.
  2309   * generate and return code to allocate
  2310   * copies of escaped parameters to the heap.
  2311   */
  2312  static NodeList*
  2313  paramstoheap(Type **argin, int out)
  2314  {
  2315  	Type *t;
  2316  	Iter savet;
  2317  	Node *v;
  2318  	NodeList *nn;
  2319  
  2320  	nn = nil;
  2321  	for(t = structfirst(&savet, argin); t != T; t = structnext(&savet)) {
  2322  		v = t->nname;
  2323  		if(v && v->sym && v->sym->name[0] == '~')
  2324  			v = N;
  2325  		// In precisestack mode, the garbage collector assumes results
  2326  		// are always live, so zero them always.
  2327  		if(out && (precisestack_enabled || (v == N && hasdefer))) {
  2328  			// Defer might stop a panic and show the
  2329  			// return values as they exist at the time of panic.
  2330  			// Make sure to zero them on entry to the function.
  2331  			nn = list(nn, nod(OAS, nodarg(t, 1), N));
  2332  		}
  2333  		if(v == N || !(v->class & PHEAP))
  2334  			continue;
  2335  
  2336  		// generate allocation & copying code
  2337  		if(v->alloc == nil)
  2338  			v->alloc = callnew(v->type);
  2339  		nn = list(nn, nod(OAS, v->heapaddr, v->alloc));
  2340  		if((v->class & ~PHEAP) != PPARAMOUT)
  2341  			nn = list(nn, nod(OAS, v, v->stackparam));
  2342  	}
  2343  	return nn;
  2344  }
  2345  
  2346  /*
  2347   * walk through argout parameters copying back to stack
  2348   */
  2349  static NodeList*
  2350  returnsfromheap(Type **argin)
  2351  {
  2352  	Type *t;
  2353  	Iter savet;
  2354  	Node *v;
  2355  	NodeList *nn;
  2356  
  2357  	nn = nil;
  2358  	for(t = structfirst(&savet, argin); t != T; t = structnext(&savet)) {
  2359  		v = t->nname;
  2360  		if(v == N || v->class != (PHEAP|PPARAMOUT))
  2361  			continue;
  2362  		nn = list(nn, nod(OAS, v->stackparam, v));
  2363  	}
  2364  	return nn;
  2365  }
  2366  
  2367  /*
  2368   * take care of migrating any function in/out args
  2369   * between the stack and the heap.  adds code to
  2370   * curfn's before and after lists.
  2371   */
  2372  static void
  2373  heapmoves(void)
  2374  {
  2375  	NodeList *nn;
  2376  	int32 lno;
  2377  
  2378  	lno = lineno;
  2379  	lineno = curfn->lineno;
  2380  	nn = paramstoheap(getthis(curfn->type), 0);
  2381  	nn = concat(nn, paramstoheap(getinarg(curfn->type), 0));
  2382  	nn = concat(nn, paramstoheap(getoutarg(curfn->type), 1));
  2383  	curfn->enter = concat(curfn->enter, nn);
  2384  	lineno = curfn->endlineno;
  2385  	curfn->exit = returnsfromheap(getoutarg(curfn->type));
  2386  	lineno = lno;
  2387  }
  2388  
  2389  static Node*
  2390  vmkcall(Node *fn, Type *t, NodeList **init, va_list va)
  2391  {
  2392  	int i, n;
  2393  	Node *r;
  2394  	NodeList *args;
  2395  
  2396  	if(fn->type == T || fn->type->etype != TFUNC)
  2397  		fatal("mkcall %N %T", fn, fn->type);
  2398  
  2399  	args = nil;
  2400  	n = fn->type->intuple;
  2401  	for(i=0; i<n; i++)
  2402  		args = list(args, va_arg(va, Node*));
  2403  
  2404  	r = nod(OCALL, fn, N);
  2405  	r->list = args;
  2406  	if(fn->type->outtuple > 0)
  2407  		typecheck(&r, Erv | Efnstruct);
  2408  	else
  2409  		typecheck(&r, Etop);
  2410  	walkexpr(&r, init);
  2411  	r->type = t;
  2412  	return r;
  2413  }
  2414  
  2415  Node*
  2416  mkcall(char *name, Type *t, NodeList **init, ...)
  2417  {
  2418  	Node *r;
  2419  	va_list va;
  2420  
  2421  	va_start(va, init);
  2422  	r = vmkcall(syslook(name, 0), t, init, va);
  2423  	va_end(va);
  2424  	return r;
  2425  }
  2426  
  2427  Node*
  2428  mkcall1(Node *fn, Type *t, NodeList **init, ...)
  2429  {
  2430  	Node *r;
  2431  	va_list va;
  2432  
  2433  	va_start(va, init);
  2434  	r = vmkcall(fn, t, init, va);
  2435  	va_end(va);
  2436  	return r;
  2437  }
  2438  
  2439  Node*
  2440  conv(Node *n, Type *t)
  2441  {
  2442  	if(eqtype(n->type, t))
  2443  		return n;
  2444  	n = nod(OCONV, n, N);
  2445  	n->type = t;
  2446  	typecheck(&n, Erv);
  2447  	return n;
  2448  }
  2449  
  2450  Node*
  2451  chanfn(char *name, int n, Type *t)
  2452  {
  2453  	Node *fn;
  2454  	int i;
  2455  
  2456  	if(t->etype != TCHAN)
  2457  		fatal("chanfn %T", t);
  2458  	fn = syslook(name, 1);
  2459  	for(i=0; i<n; i++)
  2460  		argtype(fn, t->type);
  2461  	return fn;
  2462  }
  2463  
  2464  static Node*
  2465  mapfn(char *name, Type *t)
  2466  {
  2467  	Node *fn;
  2468  
  2469  	if(t->etype != TMAP)
  2470  		fatal("mapfn %T", t);
  2471  	fn = syslook(name, 1);
  2472  	argtype(fn, t->down);
  2473  	argtype(fn, t->type);
  2474  	argtype(fn, t->down);
  2475  	argtype(fn, t->type);
  2476  	return fn;
  2477  }
  2478  
  2479  static Node*
  2480  mapfndel(char *name, Type *t)
  2481  {
  2482  	Node *fn;
  2483  
  2484  	if(t->etype != TMAP)
  2485  		fatal("mapfn %T", t);
  2486  	fn = syslook(name, 1);
  2487  	argtype(fn, t->down);
  2488  	argtype(fn, t->type);
  2489  	argtype(fn, t->down);
  2490  	return fn;
  2491  }
  2492  
  2493  static Node*
  2494  addstr(Node *n, NodeList **init)
  2495  {
  2496  	Node *r, *cat, *typstr;
  2497  	NodeList *in, *args;
  2498  	int i, count;
  2499  
  2500  	count = 0;
  2501  	for(r=n; r->op == OADDSTR; r=r->left)
  2502  		count++;	// r->right
  2503  	count++;	// r
  2504  
  2505  	// prepare call of runtime.catstring of type int, string, string, string
  2506  	// with as many strings as we have.
  2507  	cat = syslook("concatstring", 1);
  2508  	cat->type = T;
  2509  	cat->ntype = nod(OTFUNC, N, N);
  2510  	in = list1(nod(ODCLFIELD, N, typenod(types[TINT])));	// count
  2511  	typstr = typenod(types[TSTRING]);
  2512  	for(i=0; i<count; i++)
  2513  		in = list(in, nod(ODCLFIELD, N, typstr));
  2514  	cat->ntype->list = in;
  2515  	cat->ntype->rlist = list1(nod(ODCLFIELD, N, typstr));
  2516  
  2517  	args = nil;
  2518  	for(r=n; r->op == OADDSTR; r=r->left)
  2519  		args = concat(list1(conv(r->right, types[TSTRING])), args);
  2520  	args = concat(list1(conv(r, types[TSTRING])), args);
  2521  	args = concat(list1(nodintconst(count)), args);
  2522  
  2523  	r = nod(OCALL, cat, N);
  2524  	r->list = args;
  2525  	typecheck(&r, Erv);
  2526  	walkexpr(&r, init);
  2527  	r->type = n->type;
  2528  
  2529  	return r;
  2530  }
  2531  
  2532  // expand append(l1, l2...) to
  2533  //   init {
  2534  //     s := l1
  2535  //     if n := len(l1) + len(l2) - cap(s); n > 0 {
  2536  //       s = growslice(s, n)
  2537  //     }
  2538  //     s = s[:len(l1)+len(l2)]
  2539  //     memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
  2540  //   }
  2541  //   s
  2542  //
  2543  // l2 is allowed to be a string.
  2544  static Node*
  2545  appendslice(Node *n, NodeList **init)
  2546  {
  2547  	NodeList *l;
  2548  	Node *l1, *l2, *nt, *nif, *fn;
  2549  	Node *nptr1, *nptr2, *nwid;
  2550  	Node *s;
  2551  
  2552  	walkexprlistsafe(n->list, init);
  2553  
  2554  	// walkexprlistsafe will leave OINDEX (s[n]) alone if both s
  2555  	// and n are name or literal, but those may index the slice we're
  2556  	// modifying here.  Fix explicitly.
  2557  	for(l=n->list; l; l=l->next)
  2558  		l->n = cheapexpr(l->n, init);
  2559  
  2560  	l1 = n->list->n;
  2561  	l2 = n->list->next->n;
  2562  
  2563  	s = temp(l1->type); // var s []T
  2564  	l = nil;
  2565  	l = list(l, nod(OAS, s, l1)); // s = l1
  2566  
  2567  	nt = temp(types[TINT]);
  2568  	nif = nod(OIF, N, N);
  2569  	// n := len(s) + len(l2) - cap(s)
  2570  	nif->ninit = list1(nod(OAS, nt,
  2571  		nod(OSUB, nod(OADD, nod(OLEN, s, N), nod(OLEN, l2, N)), nod(OCAP, s, N))));
  2572  	nif->ntest = nod(OGT, nt, nodintconst(0));
  2573  	// instantiate growslice(Type*, []any, int64) []any
  2574  	fn = syslook("growslice", 1);
  2575  	argtype(fn, s->type->type);
  2576  	argtype(fn, s->type->type);
  2577  
  2578  	// s = growslice(T, s, n)
  2579  	nif->nbody = list1(nod(OAS, s, mkcall1(fn, s->type, &nif->ninit,
  2580  					       typename(s->type),
  2581  					       s,
  2582  					       conv(nt, types[TINT64]))));
  2583  
  2584  	l = list(l, nif);
  2585  
  2586  	if(flag_race) {
  2587  		// rely on runtime to instrument copy.
  2588  		// copy(s[len(l1):len(l1)+len(l2)], l2)
  2589  		nptr1 = nod(OSLICE, s, nod(OKEY,
  2590  			nod(OLEN, l1, N),
  2591  			nod(OADD, nod(OLEN, l1, N), nod(OLEN, l2, N))));
  2592  		nptr1->etype = 1;
  2593  		nptr2 = l2;
  2594  		if(l2->type->etype == TSTRING)
  2595  			fn = syslook("slicestringcopy", 1);
  2596  		else
  2597  			fn = syslook("copy", 1);
  2598  		argtype(fn, l1->type);
  2599  		argtype(fn, l2->type);
  2600  		l = list(l, mkcall1(fn, types[TINT], init,
  2601  				nptr1, nptr2,
  2602  				nodintconst(s->type->type->width)));
  2603  	} else {
  2604  		// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
  2605  		nptr1 = nod(OINDEX, s, nod(OLEN, l1, N));
  2606  		nptr1->bounded = 1;
  2607  		nptr1 = nod(OADDR, nptr1, N);
  2608  
  2609  		nptr2 = nod(OSPTR, l2, N);
  2610  
  2611  		fn = syslook("memmove", 1);
  2612  		argtype(fn, s->type->type);	// 1 old []any
  2613  		argtype(fn, s->type->type);	// 2 ret []any
  2614  
  2615  		nwid = cheapexpr(conv(nod(OLEN, l2, N), types[TUINTPTR]), &l);
  2616  		nwid = nod(OMUL, nwid, nodintconst(s->type->type->width));
  2617  		l = list(l, mkcall1(fn, T, init, nptr1, nptr2, nwid));
  2618  	}
  2619  
  2620  	// s = s[:len(l1)+len(l2)]
  2621  	nt = nod(OADD, nod(OLEN, l1, N), nod(OLEN, l2, N));
  2622  	nt = nod(OSLICE, s, nod(OKEY, N, nt));
  2623  	nt->etype = 1;
  2624  	l = list(l, nod(OAS, s, nt));
  2625  
  2626  	typechecklist(l, Etop);
  2627  	walkstmtlist(l);
  2628  	*init = concat(*init, l);
  2629  	return s;
  2630  }
  2631  
  2632  // expand append(src, a [, b]* ) to
  2633  //
  2634  //   init {
  2635  //     s := src
  2636  //     const argc = len(args) - 1
  2637  //     if cap(s) - len(s) < argc {
  2638  //	    s = growslice(s, argc)
  2639  //     }
  2640  //     n := len(s)
  2641  //     s = s[:n+argc]
  2642  //     s[n] = a
  2643  //     s[n+1] = b
  2644  //     ...
  2645  //   }
  2646  //   s
  2647  static Node*
  2648  append(Node *n, NodeList **init)
  2649  {
  2650  	NodeList *l, *a;
  2651  	Node *nsrc, *ns, *nn, *na, *nx, *fn;
  2652  	int argc;
  2653  
  2654  	walkexprlistsafe(n->list, init);
  2655  
  2656  	// walkexprlistsafe will leave OINDEX (s[n]) alone if both s
  2657  	// and n are name or literal, but those may index the slice we're
  2658  	// modifying here.  Fix explicitly.
  2659  	for(l=n->list; l; l=l->next)
  2660  		l->n = cheapexpr(l->n, init);
  2661  
  2662  	nsrc = n->list->n;
  2663  	argc = count(n->list) - 1;
  2664  	if (argc < 1) {
  2665  		return nsrc;
  2666  	}
  2667  
  2668  	l = nil;
  2669  
  2670  	ns = temp(nsrc->type);
  2671  	l = list(l, nod(OAS, ns, nsrc));  // s = src
  2672  
  2673  	na = nodintconst(argc);		// const argc
  2674  	nx = nod(OIF, N, N);		// if cap(s) - len(s) < argc
  2675  	nx->ntest = nod(OLT, nod(OSUB, nod(OCAP, ns, N), nod(OLEN, ns, N)), na);
  2676  
  2677  	fn = syslook("growslice", 1);	//   growslice(<type>, old []T, n int64) (ret []T)
  2678  	argtype(fn, ns->type->type);	// 1 old []any
  2679  	argtype(fn, ns->type->type);	// 2 ret []any
  2680  
  2681  	nx->nbody = list1(nod(OAS, ns, mkcall1(fn,  ns->type, &nx->ninit,
  2682  					       typename(ns->type),
  2683  					       ns,
  2684  					       conv(na, types[TINT64]))));
  2685  	l = list(l, nx);
  2686  
  2687  	nn = temp(types[TINT]);
  2688  	l = list(l, nod(OAS, nn, nod(OLEN, ns, N)));	 // n = len(s)
  2689  
  2690  	nx = nod(OSLICE, ns, nod(OKEY, N, nod(OADD, nn, na)));	 // ...s[:n+argc]
  2691  	nx->etype = 1;
  2692  	l = list(l, nod(OAS, ns, nx));			// s = s[:n+argc]
  2693  
  2694  	for (a = n->list->next;	 a != nil; a = a->next) {
  2695  		nx = nod(OINDEX, ns, nn);		// s[n] ...
  2696  		nx->bounded = 1;
  2697  		l = list(l, nod(OAS, nx, a->n));	// s[n] = arg
  2698  		if (a->next != nil)
  2699  			l = list(l, nod(OAS, nn, nod(OADD, nn, nodintconst(1))));  // n = n + 1
  2700  	}
  2701  
  2702  	typechecklist(l, Etop);
  2703  	walkstmtlist(l);
  2704  	*init = concat(*init, l);
  2705  	return ns;
  2706  }
  2707  
  2708  // Lower copy(a, b) to a memmove call.
  2709  //
  2710  // init {
  2711  //   n := len(a)
  2712  //   if n > len(b) { n = len(b) }
  2713  //   memmove(a.ptr, b.ptr, n*sizeof(elem(a)))
  2714  // }
  2715  // n;
  2716  //
  2717  // Also works if b is a string.
  2718  //
  2719  static Node*
  2720  copyany(Node *n, NodeList **init)
  2721  {
  2722  	Node *nl, *nr, *nfrm, *nto, *nif, *nlen, *nwid, *fn;
  2723  	NodeList *l;
  2724  
  2725  	walkexpr(&n->left, init);
  2726  	walkexpr(&n->right, init);
  2727  	nl = temp(n->left->type);
  2728  	nr = temp(n->right->type);
  2729  	l = nil;
  2730  	l = list(l, nod(OAS, nl, n->left));
  2731  	l = list(l, nod(OAS, nr, n->right));
  2732  
  2733  	nfrm = nod(OSPTR, nr, N);
  2734  	nto = nod(OSPTR, nl, N);
  2735  
  2736  	nlen = temp(types[TINT]);
  2737  	// n = len(to)
  2738  	l = list(l, nod(OAS, nlen, nod(OLEN, nl, N)));
  2739  	// if n > len(frm) { n = len(frm) }
  2740  	nif = nod(OIF, N, N);
  2741  	nif->ntest = nod(OGT, nlen, nod(OLEN, nr, N));
  2742  	nif->nbody = list(nif->nbody,
  2743  		nod(OAS, nlen, nod(OLEN, nr, N)));
  2744  	l = list(l, nif);
  2745  
  2746  	// Call memmove.
  2747  	fn = syslook("memmove", 1);
  2748  	argtype(fn, nl->type->type);
  2749  	argtype(fn, nl->type->type);
  2750  	nwid = temp(types[TUINTPTR]);
  2751  	l = list(l, nod(OAS, nwid, conv(nlen, types[TUINTPTR])));
  2752  	nwid = nod(OMUL, nwid, nodintconst(nl->type->type->width));
  2753  	l = list(l, mkcall1(fn, T, init, nto, nfrm, nwid));
  2754  
  2755  	typechecklist(l, Etop);
  2756  	walkstmtlist(l);
  2757  	*init = concat(*init, l);
  2758  	return nlen;
  2759  }
  2760  
  2761  // Generate frontend part for OSLICE[3][ARR|STR]
  2762  // 
  2763  static	Node*
  2764  sliceany(Node* n, NodeList **init)
  2765  {
  2766  	int bounded, slice3;
  2767  	Node *src, *lb, *hb, *cb, *bound, *chk, *chk0, *chk1, *chk2;
  2768  	int64 lbv, hbv, cbv, bv, w;
  2769  	Type *bt;
  2770  
  2771  //	print("before sliceany: %+N\n", n);
  2772  
  2773  	src = n->left;
  2774  	lb = n->right->left;
  2775  	slice3 = n->op == OSLICE3 || n->op == OSLICE3ARR;
  2776  	if(slice3) {
  2777  		hb = n->right->right->left;
  2778  		cb = n->right->right->right;
  2779  	} else {
  2780  		hb = n->right->right;
  2781  		cb = N;
  2782  	}
  2783  
  2784  	bounded = n->etype;
  2785  	
  2786  	if(n->op == OSLICESTR)
  2787  		bound = nod(OLEN, src, N);
  2788  	else
  2789  		bound = nod(OCAP, src, N);
  2790  
  2791  	typecheck(&bound, Erv);
  2792  	walkexpr(&bound, init);  // if src is an array, bound will be a const now.
  2793  
  2794  	// static checks if possible
  2795  	bv = 1LL<<50;
  2796  	if(isconst(bound, CTINT)) {
  2797  		if(!smallintconst(bound))
  2798  			yyerror("array len too large");
  2799  		else
  2800  			bv = mpgetfix(bound->val.u.xval);
  2801  	}
  2802  
  2803  	if(isconst(cb, CTINT)) {
  2804  		cbv = mpgetfix(cb->val.u.xval);
  2805  		if(cbv < 0 || cbv > bv) {
  2806  			yyerror("slice index out of bounds");
  2807  			cbv = -1;
  2808  		}
  2809  	}
  2810  	if(isconst(hb, CTINT)) {
  2811  		hbv = mpgetfix(hb->val.u.xval);
  2812  		if(hbv < 0 || hbv > bv) {
  2813  			yyerror("slice index out of bounds");
  2814  			hbv = -1;
  2815  		}
  2816  	}
  2817  	if(isconst(lb, CTINT)) {
  2818  		lbv = mpgetfix(lb->val.u.xval);
  2819  		if(lbv < 0 || lbv > bv) {
  2820  			yyerror("slice index out of bounds");
  2821  			lbv = -1;
  2822  		}
  2823  		if(lbv == 0)
  2824  			lb = N;
  2825  	}
  2826  
  2827  	// dynamic checks convert all bounds to unsigned to save us the bound < 0 comparison
  2828  	// generate
  2829  	//     if hb > bound || lb > hb { panicslice() }
  2830  	chk = N;
  2831  	chk0 = N;
  2832  	chk1 = N;
  2833  	chk2 = N;
  2834  
  2835  	bt = types[simtype[TUINT]];
  2836  	if(cb != N && cb->type->width > 4)
  2837  		bt = types[TUINT64];
  2838  	if(hb != N && hb->type->width > 4)
  2839  		bt = types[TUINT64];
  2840  	if(lb != N && lb->type->width > 4)
  2841  		bt = types[TUINT64];
  2842  
  2843  	bound = cheapexpr(conv(bound, bt), init);
  2844  
  2845  	if(cb != N) {
  2846  		cb = cheapexpr(conv(cb, bt), init);
  2847  		if(!bounded)
  2848  			chk0 = nod(OLT, bound, cb);
  2849  	} else if(slice3) {
  2850  		// When we figure out what this means, implement it.
  2851  		fatal("slice3 with cb == N"); // rejected by parser
  2852  	}
  2853  		
  2854  	if(hb != N) {
  2855  		hb = cheapexpr(conv(hb, bt), init);
  2856  		if(!bounded) {
  2857  			if(cb != N)
  2858  				chk1 = nod(OLT, cb, hb);
  2859  			else
  2860  				chk1 = nod(OLT, bound, hb);
  2861  		}
  2862  	} else if(slice3) {
  2863  		// When we figure out what this means, implement it.
  2864  		fatal("slice3 with hb == N"); // rejected by parser
  2865  	} else if(n->op == OSLICEARR) {
  2866  		hb = bound;
  2867  	} else {
  2868  		hb = nod(OLEN, src, N);
  2869  		typecheck(&hb, Erv);
  2870  		walkexpr(&hb, init);
  2871  		hb = cheapexpr(conv(hb, bt), init);
  2872  	}
  2873  
  2874  	if(lb != N) {
  2875  		lb = cheapexpr(conv(lb, bt), init);
  2876  		if(!bounded)
  2877  			chk2 = nod(OLT, hb, lb);  
  2878  	}
  2879  
  2880  	if(chk0 != N || chk1 != N || chk2 != N) {
  2881  		chk = nod(OIF, N, N);
  2882  		chk->nbody = list1(mkcall("panicslice", T, init));
  2883  		chk->likely = -1;
  2884  		if(chk0 != N)
  2885  			chk->ntest = chk0;
  2886  		if(chk1 != N) {
  2887  			if(chk->ntest == N)
  2888  				chk->ntest = chk1;
  2889  			else
  2890  				chk->ntest = nod(OOROR, chk->ntest, chk1);
  2891  		}
  2892  		if(chk2 != N) {
  2893  			if(chk->ntest == N)
  2894  				chk->ntest = chk2;
  2895  			else
  2896  				chk->ntest = nod(OOROR, chk->ntest, chk2);
  2897  		}
  2898  		typecheck(&chk, Etop);
  2899  		walkstmt(&chk);
  2900  		*init = concat(*init, chk->ninit);
  2901  		chk->ninit = nil;
  2902  		*init = list(*init, chk);
  2903  	}
  2904  	
  2905  	// prepare new cap, len and offs for backend cgen_slice
  2906  	// cap = bound [ - lo ]
  2907  	n->right = N;
  2908  	n->list = nil;
  2909  	if(!slice3)
  2910  		cb = bound;
  2911  	if(lb == N)
  2912  		bound = conv(cb, types[simtype[TUINT]]);
  2913  	else
  2914  		bound = nod(OSUB, conv(cb, types[simtype[TUINT]]), conv(lb, types[simtype[TUINT]]));
  2915  	typecheck(&bound, Erv);
  2916  	walkexpr(&bound, init);
  2917  	n->list = list(n->list, bound);
  2918  
  2919  	// len = hi [ - lo]
  2920  	if(lb == N)
  2921  		hb = conv(hb, types[simtype[TUINT]]);
  2922  	else
  2923  		hb = nod(OSUB, conv(hb, types[simtype[TUINT]]), conv(lb, types[simtype[TUINT]]));
  2924  	typecheck(&hb, Erv);
  2925  	walkexpr(&hb, init);
  2926  	n->list = list(n->list, hb);
  2927  
  2928  	// offs = [width *] lo, but omit if zero
  2929  	if(lb != N) {
  2930  		if(n->op == OSLICESTR)
  2931  			w = 1;
  2932  		else
  2933  			w = n->type->type->width;
  2934  		lb = conv(lb, types[TUINTPTR]);
  2935  		if(w > 1)
  2936  			lb = nod(OMUL, nodintconst(w), lb);
  2937  		typecheck(&lb, Erv);
  2938  		walkexpr(&lb, init);
  2939  		n->list = list(n->list, lb);
  2940  	}
  2941  
  2942  //	print("after sliceany: %+N\n", n);
  2943  
  2944  	return n;
  2945  }
  2946  
  2947  static Node*
  2948  eqfor(Type *t)
  2949  {
  2950  	int a;
  2951  	Node *n;
  2952  	Node *ntype;
  2953  	Sym *sym;
  2954  
  2955  	// Should only arrive here with large memory or
  2956  	// a struct/array containing a non-memory field/element.
  2957  	// Small memory is handled inline, and single non-memory
  2958  	// is handled during type check (OCMPSTR etc).
  2959  	a = algtype1(t, nil);
  2960  	if(a != AMEM && a != -1)
  2961  		fatal("eqfor %T", t);
  2962  
  2963  	if(a == AMEM) {
  2964  		n = syslook("memequal", 1);
  2965  		argtype(n, t);
  2966  		argtype(n, t);
  2967  		return n;
  2968  	}
  2969  
  2970  	sym = typesymprefix(".eq", t);
  2971  	n = newname(sym);
  2972  	n->class = PFUNC;
  2973  	ntype = nod(OTFUNC, N, N);
  2974  	ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(ptrto(types[TBOOL]))));
  2975  	ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
  2976  	ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(ptrto(t))));
  2977  	ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(ptrto(t))));
  2978  	typecheck(&ntype, Etype);
  2979  	n->type = ntype->type;
  2980  	return n;
  2981  }
  2982  
  2983  static int
  2984  countfield(Type *t)
  2985  {
  2986  	Type *t1;
  2987  	int n;
  2988  	
  2989  	n = 0;
  2990  	for(t1=t->type; t1!=T; t1=t1->down)
  2991  		n++;
  2992  	return n;
  2993  }
  2994  
  2995  static void
  2996  walkcompare(Node **np, NodeList **init)
  2997  {
  2998  	Node *n, *l, *r, *fn, *call, *a, *li, *ri, *expr;
  2999  	int andor, i;
  3000  	Type *t, *t1;
  3001  	static Node *tempbool;
  3002  	
  3003  	n = *np;
  3004  	
  3005  	// Must be comparison of array or struct.
  3006  	// Otherwise back end handles it.
  3007  	t = n->left->type;
  3008  	switch(t->etype) {
  3009  	default:
  3010  		return;
  3011  	case TARRAY:
  3012  		if(isslice(t))
  3013  			return;
  3014  		break;
  3015  	case TSTRUCT:
  3016  		break;
  3017  	}
  3018  	
  3019  	if(!islvalue(n->left) || !islvalue(n->right))
  3020  		goto hard;
  3021  
  3022  	l = temp(ptrto(t));
  3023  	a = nod(OAS, l, nod(OADDR, n->left, N));
  3024  	a->right->etype = 1;  // addr does not escape
  3025  	typecheck(&a, Etop);
  3026  	*init = list(*init, a);
  3027  
  3028  	r = temp(ptrto(t));
  3029  	a = nod(OAS, r, nod(OADDR, n->right, N));
  3030  	a->right->etype = 1;  // addr does not escape
  3031  	typecheck(&a, Etop);
  3032  	*init = list(*init, a);
  3033  
  3034  	expr = N;
  3035  	andor = OANDAND;
  3036  	if(n->op == ONE)
  3037  		andor = OOROR;
  3038  
  3039  	if(t->etype == TARRAY &&
  3040  		t->bound <= 4 &&
  3041  		issimple[t->type->etype]) {
  3042  		// Four or fewer elements of a basic type.
  3043  		// Unroll comparisons.
  3044  		for(i=0; i<t->bound; i++) {
  3045  			li = nod(OINDEX, l, nodintconst(i));
  3046  			ri = nod(OINDEX, r, nodintconst(i));
  3047  			a = nod(n->op, li, ri);
  3048  			if(expr == N)
  3049  				expr = a;
  3050  			else
  3051  				expr = nod(andor, expr, a);
  3052  		}
  3053  		if(expr == N)
  3054  			expr = nodbool(n->op == OEQ);
  3055  		typecheck(&expr, Erv);
  3056  		walkexpr(&expr, init);
  3057  		expr->type = n->type;
  3058  		*np = expr;
  3059  		return;
  3060  	}
  3061  	
  3062  	if(t->etype == TSTRUCT && countfield(t) <= 4) {
  3063  		// Struct of four or fewer fields.
  3064  		// Inline comparisons.
  3065  		for(t1=t->type; t1; t1=t1->down) {
  3066  			if(isblanksym(t1->sym))
  3067  				continue;
  3068  			li = nod(OXDOT, l, newname(t1->sym));
  3069  			ri = nod(OXDOT, r, newname(t1->sym));
  3070  			a = nod(n->op, li, ri);
  3071  			if(expr == N)
  3072  				expr = a;
  3073  			else
  3074  				expr = nod(andor, expr, a);
  3075  		}
  3076  		if(expr == N)
  3077  			expr = nodbool(n->op == OEQ);
  3078  		typecheck(&expr, Erv);
  3079  		walkexpr(&expr, init);
  3080  		expr->type = n->type;
  3081  		*np = expr;
  3082  		return;
  3083  	}
  3084  	
  3085  	// Chose not to inline, but still have addresses.
  3086  	// Call equality function directly.
  3087  	// The equality function requires a bool pointer for
  3088  	// storing its address, because it has to be callable
  3089  	// from C, and C can't access an ordinary Go return value.
  3090  	// To avoid creating many temporaries, cache one per function.
  3091  	if(tempbool == N || tempbool->curfn != curfn)
  3092  		tempbool = temp(types[TBOOL]);
  3093  	
  3094  	call = nod(OCALL, eqfor(t), N);
  3095  	a = nod(OADDR, tempbool, N);
  3096  	a->etype = 1;  // does not escape
  3097  	call->list = list(call->list, a);
  3098  	call->list = list(call->list, nodintconst(t->width));
  3099  	call->list = list(call->list, l);
  3100  	call->list = list(call->list, r);
  3101  	typecheck(&call, Etop);
  3102  	walkstmt(&call);
  3103  	*init = list(*init, call);
  3104  
  3105  	// tempbool cannot be used directly as multiple comparison
  3106  	// expressions may exist in the same statement. Create another
  3107  	// temporary to hold the value (its address is not taken so it can
  3108  	// be optimized away).
  3109  	r = temp(types[TBOOL]);
  3110  	a = nod(OAS, r, tempbool);
  3111  	typecheck(&a, Etop);
  3112  	walkstmt(&a);
  3113  	*init = list(*init, a);
  3114  
  3115  	if(n->op != OEQ)
  3116  		r = nod(ONOT, r, N);
  3117  	typecheck(&r, Erv);
  3118  	walkexpr(&r, init);
  3119  	*np = r;
  3120  	return;
  3121  
  3122  hard:
  3123  	// Cannot take address of one or both of the operands.
  3124  	// Instead, pass directly to runtime helper function.
  3125  	// Easier on the stack than passing the address
  3126  	// of temporary variables, because we are better at reusing
  3127  	// the argument space than temporary variable space.
  3128  	fn = syslook("equal", 1);
  3129  	l = n->left;
  3130  	r = n->right;
  3131  	argtype(fn, n->left->type);
  3132  	argtype(fn, n->left->type);
  3133  	r = mkcall1(fn, n->type, init, typename(n->left->type), l, r);
  3134  	if(n->op == ONE) {
  3135  		r = nod(ONOT, r, N);
  3136  		typecheck(&r, Erv);
  3137  	}
  3138  	*np = r;
  3139  	return;
  3140  }
  3141  
  3142  static int
  3143  samecheap(Node *a, Node *b)
  3144  {
  3145  	Node *ar, *br;
  3146  	while(a != N && b != N && a->op == b->op) {
  3147  		switch(a->op) {
  3148  		default:
  3149  			return 0;
  3150  		case ONAME:
  3151  			return a == b;
  3152  		case ODOT:
  3153  		case ODOTPTR:
  3154  			ar = a->right;
  3155  			br = b->right;
  3156  			if(ar->op != ONAME || br->op != ONAME || ar->sym != br->sym)
  3157  				return 0;
  3158  			break;
  3159  		case OINDEX:
  3160  			ar = a->right;
  3161  			br = b->right;
  3162  			if(!isconst(ar, CTINT) || !isconst(br, CTINT) || mpcmpfixfix(ar->val.u.xval, br->val.u.xval) != 0)
  3163  				return 0;
  3164  			break;
  3165  		}
  3166  		a = a->left;
  3167  		b = b->left;
  3168  	}
  3169  	return 0;
  3170  }
  3171  
  3172  static void
  3173  walkrotate(Node **np)
  3174  {
  3175  	int w, sl, sr, s;
  3176  	Node *l, *r;
  3177  	Node *n;
  3178  	
  3179  	n = *np;
  3180  
  3181  	// Want << | >> or >> | << or << ^ >> or >> ^ << on unsigned value.
  3182  	l = n->left;
  3183  	r = n->right;
  3184  	if((n->op != OOR && n->op != OXOR) ||
  3185  	   (l->op != OLSH && l->op != ORSH) ||
  3186  	   (r->op != OLSH && r->op != ORSH) ||
  3187  	   n->type == T || issigned[n->type->etype] ||
  3188  	   l->op == r->op) {
  3189  		return;
  3190  	}
  3191  
  3192  	// Want same, side effect-free expression on lhs of both shifts.
  3193  	if(!samecheap(l->left, r->left))
  3194  		return;
  3195  	
  3196  	// Constants adding to width?
  3197  	w = l->type->width * 8;
  3198  	if(smallintconst(l->right) && smallintconst(r->right)) {
  3199  		if((sl=mpgetfix(l->right->val.u.xval)) >= 0 && (sr=mpgetfix(r->right->val.u.xval)) >= 0 && sl+sr == w)
  3200  			goto yes;
  3201  		return;
  3202  	}
  3203  	
  3204  	// TODO: Could allow s and 32-s if s is bounded (maybe s&31 and 32-s&31).
  3205  	return;
  3206  	
  3207  yes:
  3208  	// Rewrite left shift half to left rotate.
  3209  	if(l->op == OLSH)
  3210  		n = l;
  3211  	else
  3212  		n = r;
  3213  	n->op = OLROT;
  3214  	
  3215  	// Remove rotate 0 and rotate w.
  3216  	s = mpgetfix(n->right->val.u.xval);
  3217  	if(s == 0 || s == w)
  3218  		n = n->left;
  3219  
  3220  	*np = n;
  3221  	return;
  3222  }
  3223  
  3224  /*
  3225   * walkmul rewrites integer multiplication by powers of two as shifts.
  3226   */
  3227  static void
  3228  walkmul(Node **np, NodeList **init)
  3229  {
  3230  	Node *n, *nl, *nr;
  3231  	int pow, neg, w;
  3232  	
  3233  	n = *np;
  3234  	if(!isint[n->type->etype])
  3235  		return;
  3236  
  3237  	if(n->right->op == OLITERAL) {
  3238  		nl = n->left;
  3239  		nr = n->right;
  3240  	} else if(n->left->op == OLITERAL) {
  3241  		nl = n->right;
  3242  		nr = n->left;
  3243  	} else
  3244  		return;
  3245  
  3246  	neg = 0;
  3247  
  3248  	// x*0 is 0 (and side effects of x).
  3249  	if(mpgetfix(nr->val.u.xval) == 0) {
  3250  		cheapexpr(nl, init);
  3251  		nodconst(n, n->type, 0);
  3252  		goto ret;
  3253  	}
  3254  
  3255  	// nr is a constant.
  3256  	pow = powtwo(nr);
  3257  	if(pow < 0)
  3258  		return;
  3259  	if(pow >= 1000) {
  3260  		// negative power of 2, like -16
  3261  		neg = 1;
  3262  		pow -= 1000;
  3263  	}
  3264  
  3265  	w = nl->type->width*8;
  3266  	if(pow+1 >= w)// too big, shouldn't happen
  3267  		return;
  3268  
  3269  	nl = cheapexpr(nl, init);
  3270  
  3271  	if(pow == 0) {
  3272  		// x*1 is x
  3273  		n = nl;
  3274  		goto ret;
  3275  	}
  3276  	
  3277  	n = nod(OLSH, nl, nodintconst(pow));
  3278  
  3279  ret:
  3280  	if(neg)
  3281  		n = nod(OMINUS, n, N);
  3282  
  3283  	typecheck(&n, Erv);
  3284  	walkexpr(&n, init);
  3285  	*np = n;
  3286  }
  3287  
  3288  /*
  3289   * walkdiv rewrites division by a constant as less expensive
  3290   * operations.
  3291   */
  3292  static void
  3293  walkdiv(Node **np, NodeList **init)
  3294  {
  3295  	Node *n, *nl, *nr, *nc;
  3296  	Node *n1, *n2, *n3, *n4;
  3297  	int pow; // if >= 0, nr is 1<<pow
  3298  	int s; // 1 if nr is negative.
  3299  	int w;
  3300  	Type *twide;
  3301  	Magic m;
  3302  
  3303  	n = *np;
  3304  	if(n->right->op != OLITERAL)
  3305  		return;
  3306  	// nr is a constant.
  3307  	nl = cheapexpr(n->left, init);
  3308  	nr = n->right;
  3309  
  3310  	// special cases of mod/div
  3311  	// by a constant
  3312  	w = nl->type->width*8;
  3313  	s = 0;
  3314  	pow = powtwo(nr);
  3315  	if(pow >= 1000) {
  3316  		// negative power of 2
  3317  		s = 1;
  3318  		pow -= 1000;
  3319  	}
  3320  
  3321  	if(pow+1 >= w) {
  3322  		// divisor too large.
  3323  		return;
  3324  	}
  3325  	if(pow < 0) {
  3326  		goto divbymul;
  3327  	}
  3328  
  3329  	switch(pow) {
  3330  	case 0:
  3331  		if(n->op == OMOD) {
  3332  			// nl % 1 is zero.
  3333  			nodconst(n, n->type, 0);
  3334  		} else if(s) {
  3335  			// divide by -1
  3336  			n->op = OMINUS;
  3337  			n->right = N;
  3338  		} else {
  3339  			// divide by 1
  3340  			n = nl;
  3341  		}
  3342  		break;
  3343  	default:
  3344  		if(issigned[n->type->etype]) {
  3345  			if(n->op == OMOD) {
  3346  				// signed modulo 2^pow is like ANDing
  3347  				// with the last pow bits, but if nl < 0,
  3348  				// nl & (2^pow-1) is (nl+1)%2^pow - 1.
  3349  				nc = nod(OXXX, N, N);
  3350  				nodconst(nc, types[simtype[TUINT]], w-1);
  3351  				n1 = nod(ORSH, nl, nc); // n1 = -1 iff nl < 0.
  3352  				if(pow == 1) {
  3353  					typecheck(&n1, Erv);
  3354  					n1 = cheapexpr(n1, init);
  3355  					// n = (nl+ε)&1 -ε where ε=1 iff nl<0.
  3356  					n2 = nod(OSUB, nl, n1);
  3357  					nc = nod(OXXX, N, N);
  3358  					nodconst(nc, nl->type, 1);
  3359  					n3 = nod(OAND, n2, nc);
  3360  					n = nod(OADD, n3, n1);
  3361  				} else {
  3362  					// n = (nl+ε)&(nr-1) - ε where ε=2^pow-1 iff nl<0.
  3363  					nc = nod(OXXX, N, N);
  3364  					nodconst(nc, nl->type, (1LL<<pow)-1);
  3365  					n2 = nod(OAND, n1, nc); // n2 = 2^pow-1 iff nl<0.
  3366  					typecheck(&n2, Erv);
  3367  					n2 = cheapexpr(n2, init);
  3368  
  3369  					n3 = nod(OADD, nl, n2);
  3370  					n4 = nod(OAND, n3, nc);
  3371  					n = nod(OSUB, n4, n2);
  3372  				}
  3373  				break;
  3374  			} else {
  3375  				// arithmetic right shift does not give the correct rounding.
  3376  				// if nl >= 0, nl >> n == nl / nr
  3377  				// if nl < 0, we want to add 2^n-1 first.
  3378  				nc = nod(OXXX, N, N);
  3379  				nodconst(nc, types[simtype[TUINT]], w-1);
  3380  				n1 = nod(ORSH, nl, nc); // n1 = -1 iff nl < 0.
  3381  				if(pow == 1) {
  3382  					// nl+1 is nl-(-1)
  3383  					n->left = nod(OSUB, nl, n1);
  3384  				} else {
  3385  					// Do a logical right right on -1 to keep pow bits.
  3386  					nc = nod(OXXX, N, N);
  3387  					nodconst(nc, types[simtype[TUINT]], w-pow);
  3388  					n2 = nod(ORSH, conv(n1, tounsigned(nl->type)), nc);
  3389  					n->left = nod(OADD, nl, conv(n2, nl->type));
  3390  				}
  3391  				// n = (nl + 2^pow-1) >> pow
  3392  				n->op = ORSH;
  3393  				nc = nod(OXXX, N, N);
  3394  				nodconst(nc, types[simtype[TUINT]], pow);
  3395  				n->right = nc;
  3396  				n->typecheck = 0;
  3397  			}
  3398  			if(s)
  3399  				n = nod(OMINUS, n, N);
  3400  			break;
  3401  		}
  3402  		nc = nod(OXXX, N, N);
  3403  		if(n->op == OMOD) {
  3404  			// n = nl & (nr-1)
  3405  			n->op = OAND;
  3406  			nodconst(nc, nl->type, mpgetfix(nr->val.u.xval)-1);
  3407  		} else {
  3408  			// n = nl >> pow
  3409  			n->op = ORSH;
  3410  			nodconst(nc, types[simtype[TUINT]], pow);
  3411  		}
  3412  		n->typecheck = 0;
  3413  		n->right = nc;
  3414  		break;
  3415  	}
  3416  	goto ret;
  3417  
  3418  divbymul:
  3419  	// try to do division by multiply by (2^w)/d
  3420  	// see hacker's delight chapter 10
  3421  	// TODO: support 64-bit magic multiply here.
  3422  	m.w = w;
  3423  	if(issigned[nl->type->etype]) {
  3424  		m.sd = mpgetfix(nr->val.u.xval);
  3425  		smagic(&m);
  3426  	} else {
  3427  		m.ud = mpgetfix(nr->val.u.xval);
  3428  		umagic(&m);
  3429  	}
  3430  	if(m.bad)
  3431  		return;
  3432  
  3433  	// We have a quick division method so use it
  3434  	// for modulo too.
  3435  	if(n->op == OMOD)
  3436  		goto longmod;
  3437  
  3438  	switch(simtype[nl->type->etype]) {
  3439  	default:
  3440  		return;
  3441  
  3442  	case TUINT8:
  3443  	case TUINT16:
  3444  	case TUINT32:
  3445  		// n1 = nl * magic >> w (HMUL)
  3446  		nc = nod(OXXX, N, N);
  3447  		nodconst(nc, nl->type, m.um);
  3448  		n1 = nod(OMUL, nl, nc);
  3449  		typecheck(&n1, Erv);
  3450  		n1->op = OHMUL;
  3451  		if(m.ua) {
  3452  			// Select a Go type with (at least) twice the width.
  3453  			switch(simtype[nl->type->etype]) {
  3454  			default:
  3455  				return;
  3456  			case TUINT8:
  3457  			case TUINT16:
  3458  				twide = types[TUINT32];
  3459  				break;
  3460  			case TUINT32:
  3461  				twide = types[TUINT64];
  3462  				break;
  3463  			case TINT8:
  3464  			case TINT16:
  3465  				twide = types[TINT32];
  3466  				break;
  3467  			case TINT32:
  3468  				twide = types[TINT64];
  3469  				break;
  3470  			}
  3471  
  3472  			// add numerator (might overflow).
  3473  			// n2 = (n1 + nl)
  3474  			n2 = nod(OADD, conv(n1, twide), conv(nl, twide));
  3475  
  3476  			// shift by m.s
  3477  			nc = nod(OXXX, N, N);
  3478  			nodconst(nc, types[TUINT], m.s);
  3479  			n = conv(nod(ORSH, n2, nc), nl->type);
  3480  		} else {
  3481  			// n = n1 >> m.s
  3482  			nc = nod(OXXX, N, N);
  3483  			nodconst(nc, types[TUINT], m.s);
  3484  			n = nod(ORSH, n1, nc);
  3485  		}
  3486  		break;
  3487  
  3488  	case TINT8:
  3489  	case TINT16:
  3490  	case TINT32:
  3491  		// n1 = nl * magic >> w
  3492  		nc = nod(OXXX, N, N);
  3493  		nodconst(nc, nl->type, m.sm);
  3494  		n1 = nod(OMUL, nl, nc);
  3495  		typecheck(&n1, Erv);
  3496  		n1->op = OHMUL;
  3497  		if(m.sm < 0) {
  3498  			// add the numerator.
  3499  			n1 = nod(OADD, n1, nl);
  3500  		}
  3501  		// shift by m.s
  3502  		nc = nod(OXXX, N, N);
  3503  		nodconst(nc, types[TUINT], m.s);
  3504  		n2 = conv(nod(ORSH, n1, nc), nl->type);
  3505  		// add 1 iff n1 is negative.
  3506  		nc = nod(OXXX, N, N);
  3507  		nodconst(nc, types[TUINT], w-1);
  3508  		n3 = nod(ORSH, nl, nc); // n4 = -1 iff n1 is negative.
  3509  		n = nod(OSUB, n2, n3);
  3510  		// apply sign.
  3511  		if(m.sd < 0)
  3512  			n = nod(OMINUS, n, N);
  3513  		break;
  3514  	}
  3515  	goto ret;
  3516  
  3517  longmod:
  3518  	// rewrite as A%B = A - (A/B*B).
  3519  	n1 = nod(ODIV, nl, nr);
  3520  	n2 = nod(OMUL, n1, nr);
  3521  	n = nod(OSUB, nl, n2);
  3522  	goto ret;
  3523  
  3524  ret:
  3525  	typecheck(&n, Erv);
  3526  	walkexpr(&n, init);
  3527  	*np = n;
  3528  }
  3529  
  3530  // return 1 if integer n must be in range [0, max), 0 otherwise
  3531  static int
  3532  bounded(Node *n, int64 max)
  3533  {
  3534  	int64 v;
  3535  	int32 bits;
  3536  	int sign;
  3537  
  3538  	if(n->type == T || !isint[n->type->etype])
  3539  		return 0;
  3540  
  3541  	sign = issigned[n->type->etype];
  3542  	bits = 8*n->type->width;
  3543  
  3544  	if(smallintconst(n)) {
  3545  		v = mpgetfix(n->val.u.xval);
  3546  		return 0 <= v && v < max;
  3547  	}
  3548  
  3549  	switch(n->op) {
  3550  	case OAND:
  3551  		v = -1;
  3552  		if(smallintconst(n->left)) {
  3553  			v = mpgetfix(n->left->val.u.xval);
  3554  		} else if(smallintconst(n->right)) {
  3555  			v = mpgetfix(n->right->val.u.xval);
  3556  		}
  3557  		if(0 <= v && v < max)
  3558  			return 1;
  3559  		break;
  3560  
  3561  	case OMOD:
  3562  		if(!sign && smallintconst(n->right)) {
  3563  			v = mpgetfix(n->right->val.u.xval);
  3564  			if(0 <= v && v <= max)
  3565  				return 1;
  3566  		}
  3567  		break;
  3568  	
  3569  	case ODIV:
  3570  		if(!sign && smallintconst(n->right)) {
  3571  			v = mpgetfix(n->right->val.u.xval);
  3572  			while(bits > 0 && v >= 2) {
  3573  				bits--;
  3574  				v >>= 1;
  3575  			}
  3576  		}
  3577  		break;
  3578  	
  3579  	case ORSH:
  3580  		if(!sign && smallintconst(n->right)) {
  3581  			v = mpgetfix(n->right->val.u.xval);
  3582  			if(v > bits)
  3583  				return 1;
  3584  			bits -= v;
  3585  		}
  3586  		break;
  3587  	}
  3588  	
  3589  	if(!sign && bits <= 62 && (1LL<<bits) <= max)
  3590  		return 1;
  3591  	
  3592  	return 0;
  3593  }
  3594  
  3595  void
  3596  usefield(Node *n)
  3597  {
  3598  	Type *field, *l;
  3599  
  3600  	if(!fieldtrack_enabled)
  3601  		return;
  3602  
  3603  	switch(n->op) {
  3604  	default:
  3605  		fatal("usefield %O", n->op);
  3606  	case ODOT:
  3607  	case ODOTPTR:
  3608  		break;
  3609  	}
  3610  	
  3611  	field = n->paramfld;
  3612  	if(field == T)
  3613  		fatal("usefield %T %S without paramfld", n->left->type, n->right->sym);
  3614  	if(field->note == nil || strstr(field->note->s, "go:\"track\"") == nil)
  3615  		return;
  3616  
  3617  	// dedup on list
  3618  	if(field->lastfn == curfn)
  3619  		return;
  3620  	field->lastfn = curfn;
  3621  	field->outer = n->left->type;
  3622  	if(isptr[field->outer->etype])
  3623  		field->outer = field->outer->type;
  3624  	if(field->outer->sym == S)
  3625  		yyerror("tracked field must be in named struct type");
  3626  	if(!exportname(field->sym->name))
  3627  		yyerror("tracked field must be exported (upper case)");
  3628  
  3629  	l = typ(0);
  3630  	l->type = field;
  3631  	l->down = curfn->paramfld;
  3632  	curfn->paramfld = l;
  3633  }
  3634  
  3635  static int
  3636  candiscardlist(NodeList *l)
  3637  {
  3638  	for(; l; l=l->next)
  3639  		if(!candiscard(l->n))
  3640  			return 0;
  3641  	return 1;
  3642  }
  3643  
  3644  int
  3645  candiscard(Node *n)
  3646  {
  3647  	if(n == N)
  3648  		return 1;
  3649  	
  3650  	switch(n->op) {
  3651  	default:
  3652  		return 0;
  3653  
  3654  	case ONAME:
  3655  	case ONONAME:
  3656  	case OTYPE:
  3657  	case OPACK:
  3658  	case OLITERAL:
  3659  	case OADD:
  3660  	case OSUB:
  3661  	case OOR:
  3662  	case OXOR:
  3663  	case OADDSTR:
  3664  	case OADDR:
  3665  	case OANDAND:
  3666  	case OARRAYBYTESTR:
  3667  	case OARRAYRUNESTR:
  3668  	case OSTRARRAYBYTE:
  3669  	case OSTRARRAYRUNE:
  3670  	case OCAP:
  3671  	case OCMPIFACE:
  3672  	case OCMPSTR:
  3673  	case OCOMPLIT:
  3674  	case OMAPLIT:
  3675  	case OSTRUCTLIT:
  3676  	case OARRAYLIT:
  3677  	case OPTRLIT:
  3678  	case OCONV:
  3679  	case OCONVIFACE:
  3680  	case OCONVNOP:
  3681  	case ODOT:
  3682  	case OEQ:
  3683  	case ONE:
  3684  	case OLT:
  3685  	case OLE:
  3686  	case OGT:
  3687  	case OGE:
  3688  	case OKEY:
  3689  	case OLEN:
  3690  	case OMUL:
  3691  	case OLSH:
  3692  	case ORSH:
  3693  	case OAND:
  3694  	case OANDNOT:
  3695  	case ONEW:
  3696  	case ONOT:
  3697  	case OCOM:
  3698  	case OPLUS:
  3699  	case OMINUS:
  3700  	case OOROR:
  3701  	case OPAREN:
  3702  	case ORUNESTR:
  3703  	case OREAL:
  3704  	case OIMAG:
  3705  	case OCOMPLEX:
  3706  		// Discardable as long as the subpieces are.
  3707  		break;
  3708  
  3709  	case ODIV:
  3710  	case OMOD:
  3711  		// Discardable as long as we know it's not division by zero.
  3712  		if(isconst(n->right, CTINT) && mpcmpfixc(n->right->val.u.xval, 0) != 0)
  3713  			break;
  3714  		if(isconst(n->right, CTFLT) && mpcmpfltc(n->right->val.u.fval, 0) != 0)
  3715  			break;
  3716  		return 0;
  3717  
  3718  	case OMAKECHAN:
  3719  	case OMAKEMAP:
  3720  		// Discardable as long as we know it won't fail because of a bad size.
  3721  		if(isconst(n->left, CTINT) && mpcmpfixc(n->left->val.u.xval, 0) == 0)
  3722  			break;
  3723  		return 0;
  3724  	
  3725  	case OMAKESLICE:
  3726  		// Difficult to tell what sizes are okay.
  3727  		return 0;		
  3728  	}
  3729  	
  3730  	if(!candiscard(n->left) ||
  3731  	   !candiscard(n->right) ||
  3732  	   !candiscard(n->ntest) ||
  3733  	   !candiscard(n->nincr) ||
  3734  	   !candiscardlist(n->ninit) ||
  3735  	   !candiscardlist(n->nbody) ||
  3736  	   !candiscardlist(n->nelse) ||
  3737  	   !candiscardlist(n->list) ||
  3738  	   !candiscardlist(n->rlist)) {
  3739  		return 0;
  3740  	}
  3741  	
  3742  	return 1;
  3743  }