github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/8g/cgen.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  // TODO(rsc):
     6  //	assume CLD?
     7  
     8  #include <u.h>
     9  #include <libc.h>
    10  #include "gg.h"
    11  
    12  void
    13  mgen(Node *n, Node *n1, Node *rg)
    14  {
    15  	Node n2;
    16  
    17  	n1->op = OEMPTY;
    18  
    19  	if(n->addable) {
    20  		*n1 = *n;
    21  		if(n1->op == OREGISTER || n1->op == OINDREG)
    22  			reg[n->val.u.reg]++;
    23  		return;
    24  	}
    25  	tempname(n1, n->type);
    26  	cgen(n, n1);
    27  	if(n->type->width <= widthptr || isfloat[n->type->etype]) {
    28  		n2 = *n1;
    29  		regalloc(n1, n->type, rg);
    30  		gmove(&n2, n1);
    31  	}
    32  }
    33  
    34  void
    35  mfree(Node *n)
    36  {
    37  	if(n->op == OREGISTER)
    38  		regfree(n);
    39  }
    40  
    41  /*
    42   * generate:
    43   *	res = n;
    44   * simplifies and calls gmove.
    45   *
    46   * TODO:
    47   *	sudoaddable
    48   */
    49  void
    50  cgen(Node *n, Node *res)
    51  {
    52  	Node *nl, *nr, *r, n1, n2, nt;
    53  	Prog *p1, *p2, *p3;
    54  	int a;
    55  
    56  	if(debug['g']) {
    57  		dump("\ncgen-n", n);
    58  		dump("cgen-res", res);
    59  	}
    60  
    61  	if(n == N || n->type == T)
    62  		fatal("cgen: n nil");
    63  	if(res == N || res->type == T)
    64  		fatal("cgen: res nil");
    65  
    66  	switch(n->op) {
    67  	case OSLICE:
    68  	case OSLICEARR:
    69  	case OSLICESTR:
    70  	case OSLICE3:
    71  	case OSLICE3ARR:
    72  		if (res->op != ONAME || !res->addable) {
    73  			tempname(&n1, n->type);
    74  			cgen_slice(n, &n1);
    75  			cgen(&n1, res);
    76  		} else
    77  			cgen_slice(n, res);
    78  		return;
    79  	case OEFACE:
    80  		if (res->op != ONAME || !res->addable) {
    81  			tempname(&n1, n->type);
    82  			cgen_eface(n, &n1);
    83  			cgen(&n1, res);
    84  		} else
    85  			cgen_eface(n, res);
    86  		return;
    87  	}
    88  
    89  	while(n->op == OCONVNOP)
    90  		n = n->left;
    91  
    92  	// function calls on both sides?  introduce temporary
    93  	if(n->ullman >= UINF && res->ullman >= UINF) {
    94  		tempname(&n1, n->type);
    95  		cgen(n, &n1);
    96  		cgen(&n1, res);
    97  		return;
    98  	}
    99  
   100  	// structs etc get handled specially
   101  	if(isfat(n->type)) {
   102  		if(n->type->width < 0)
   103  			fatal("forgot to compute width for %T", n->type);
   104  		sgen(n, res, n->type->width);
   105  		return;
   106  	}
   107  
   108  	// update addressability for string, slice
   109  	// can't do in walk because n->left->addable
   110  	// changes if n->left is an escaping local variable.
   111  	switch(n->op) {
   112  	case OSPTR:
   113  	case OLEN:
   114  		if(isslice(n->left->type) || istype(n->left->type, TSTRING))
   115  			n->addable = n->left->addable;
   116  		break;
   117  	case OCAP:
   118  		if(isslice(n->left->type))
   119  			n->addable = n->left->addable;
   120  		break;
   121  	case OITAB:
   122  		n->addable = n->left->addable;
   123  		break;
   124  	}
   125  
   126  	// if both are addressable, move
   127  	if(n->addable && res->addable) {
   128  		gmove(n, res);
   129  		return;
   130  	}
   131  
   132  	// if both are not addressable, use a temporary.
   133  	if(!n->addable && !res->addable) {
   134  		// could use regalloc here sometimes,
   135  		// but have to check for ullman >= UINF.
   136  		tempname(&n1, n->type);
   137  		cgen(n, &n1);
   138  		cgen(&n1, res);
   139  		return;
   140  	}
   141  
   142  	// if result is not addressable directly but n is,
   143  	// compute its address and then store via the address.
   144  	if(!res->addable) {
   145  		igen(res, &n1, N);
   146  		cgen(n, &n1);
   147  		regfree(&n1);
   148  		return;
   149  	}
   150  
   151  	// complex types
   152  	if(complexop(n, res)) {
   153  		complexgen(n, res);
   154  		return;
   155  	}
   156  
   157  	// otherwise, the result is addressable but n is not.
   158  	// let's do some computation.
   159  
   160  	// use ullman to pick operand to eval first.
   161  	nl = n->left;
   162  	nr = n->right;
   163  	if(nl != N && nl->ullman >= UINF)
   164  	if(nr != N && nr->ullman >= UINF) {
   165  		// both are hard
   166  		tempname(&n1, nl->type);
   167  		cgen(nl, &n1);
   168  		n2 = *n;
   169  		n2.left = &n1;
   170  		cgen(&n2, res);
   171  		return;
   172  	}
   173  
   174  	// 64-bit ops are hard on 32-bit machine.
   175  	if(is64(n->type) || is64(res->type) || n->left != N && is64(n->left->type)) {
   176  		switch(n->op) {
   177  		// math goes to cgen64.
   178  		case OMINUS:
   179  		case OCOM:
   180  		case OADD:
   181  		case OSUB:
   182  		case OMUL:
   183  		case OLROT:
   184  		case OLSH:
   185  		case ORSH:
   186  		case OAND:
   187  		case OOR:
   188  		case OXOR:
   189  			cgen64(n, res);
   190  			return;
   191  		}
   192  	}
   193  
   194  	if(nl != N && isfloat[n->type->etype] && isfloat[nl->type->etype]) {
   195  		cgen_float(n, res);
   196  		return;
   197  	}
   198  
   199  	switch(n->op) {
   200  	default:
   201  		dump("cgen", n);
   202  		fatal("cgen %O", n->op);
   203  		break;
   204  
   205  	case OREAL:
   206  	case OIMAG:
   207  	case OCOMPLEX:
   208  		fatal("unexpected complex");
   209  		return;
   210  
   211  	// these call bgen to get a bool value
   212  	case OOROR:
   213  	case OANDAND:
   214  	case OEQ:
   215  	case ONE:
   216  	case OLT:
   217  	case OLE:
   218  	case OGE:
   219  	case OGT:
   220  	case ONOT:
   221  		p1 = gbranch(AJMP, T, 0);
   222  		p2 = pc;
   223  		gmove(nodbool(1), res);
   224  		p3 = gbranch(AJMP, T, 0);
   225  		patch(p1, pc);
   226  		bgen(n, 1, 0, p2);
   227  		gmove(nodbool(0), res);
   228  		patch(p3, pc);
   229  		return;
   230  
   231  	case OPLUS:
   232  		cgen(nl, res);
   233  		return;
   234  
   235  	case OMINUS:
   236  	case OCOM:
   237  		a = optoas(n->op, nl->type);
   238  		goto uop;
   239  
   240  	// symmetric binary
   241  	case OAND:
   242  	case OOR:
   243  	case OXOR:
   244  	case OADD:
   245  	case OMUL:
   246  		a = optoas(n->op, nl->type);
   247  		if(a == AIMULB) {
   248  			cgen_bmul(n->op, nl, nr, res);
   249  			break;
   250  		}
   251  		goto sbop;
   252  
   253  	// asymmetric binary
   254  	case OSUB:
   255  		a = optoas(n->op, nl->type);
   256  		goto abop;
   257  
   258  	case OHMUL:
   259  		cgen_hmul(nl, nr, res);
   260  		break;
   261  
   262  	case OCONV:
   263  		if(eqtype(n->type, nl->type) || noconv(n->type, nl->type)) {
   264  			cgen(nl, res);
   265  			break;
   266  		}
   267  
   268  		tempname(&n2, n->type);
   269  		mgen(nl, &n1, res);
   270  		gmove(&n1, &n2);
   271  		gmove(&n2, res);
   272  		mfree(&n1);
   273  		break;
   274  
   275  	case ODOT:
   276  	case ODOTPTR:
   277  	case OINDEX:
   278  	case OIND:
   279  	case ONAME:	// PHEAP or PPARAMREF var
   280  		igen(n, &n1, res);
   281  		gmove(&n1, res);
   282  		regfree(&n1);
   283  		break;
   284  
   285  	case OITAB:
   286  		igen(nl, &n1, res);
   287  		n1.type = ptrto(types[TUINTPTR]);
   288  		gmove(&n1, res);
   289  		regfree(&n1);
   290  		break;
   291  
   292  	case OSPTR:
   293  		// pointer is the first word of string or slice.
   294  		if(isconst(nl, CTSTR)) {
   295  			regalloc(&n1, types[tptr], res);
   296  			p1 = gins(ALEAL, N, &n1);
   297  			datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
   298  			gmove(&n1, res);
   299  			regfree(&n1);
   300  			break;
   301  		}
   302  		igen(nl, &n1, res);
   303  		n1.type = n->type;
   304  		gmove(&n1, res);
   305  		regfree(&n1);
   306  		break;
   307  
   308  	case OLEN:
   309  		if(istype(nl->type, TMAP) || istype(nl->type, TCHAN)) {
   310  			// map has len in the first 32-bit word.
   311  			// a zero pointer means zero length
   312  			tempname(&n1, types[tptr]);
   313  			cgen(nl, &n1);
   314  			regalloc(&n2, types[tptr], N);
   315  			gmove(&n1, &n2);
   316  			n1 = n2;
   317  
   318  			nodconst(&n2, types[tptr], 0);
   319  			gins(optoas(OCMP, types[tptr]), &n1, &n2);
   320  			p1 = gbranch(optoas(OEQ, types[tptr]), T, -1);
   321  
   322  			n2 = n1;
   323  			n2.op = OINDREG;
   324  			n2.type = types[TINT32];
   325  			gmove(&n2, &n1);
   326  
   327  			patch(p1, pc);
   328  
   329  			gmove(&n1, res);
   330  			regfree(&n1);
   331  			break;
   332  		}
   333  		if(istype(nl->type, TSTRING) || isslice(nl->type)) {
   334  			// both slice and string have len one pointer into the struct.
   335  			igen(nl, &n1, res);
   336  			n1.type = types[TUINT32];
   337  			n1.xoffset += Array_nel;
   338  			gmove(&n1, res);
   339  			regfree(&n1);
   340  			break;
   341  		}
   342  		fatal("cgen: OLEN: unknown type %lT", nl->type);
   343  		break;
   344  
   345  	case OCAP:
   346  		if(istype(nl->type, TCHAN)) {
   347  			// chan has cap in the second 32-bit word.
   348  			// a zero pointer means zero length
   349  			regalloc(&n1, types[tptr], res);
   350  			cgen(nl, &n1);
   351  
   352  			nodconst(&n2, types[tptr], 0);
   353  			gins(optoas(OCMP, types[tptr]), &n1, &n2);
   354  			p1 = gbranch(optoas(OEQ, types[tptr]), T, -1);
   355  
   356  			n2 = n1;
   357  			n2.op = OINDREG;
   358  			n2.xoffset = 4;
   359  			n2.type = types[TINT32];
   360  			gmove(&n2, &n1);
   361  
   362  			patch(p1, pc);
   363  
   364  			gmove(&n1, res);
   365  			regfree(&n1);
   366  			break;
   367  		}
   368  		if(isslice(nl->type)) {
   369  			igen(nl, &n1, res);
   370  			n1.type = types[TUINT32];
   371  			n1.xoffset += Array_cap;
   372  			gmove(&n1, res);
   373  			regfree(&n1);
   374  			break;
   375  		}
   376  		fatal("cgen: OCAP: unknown type %lT", nl->type);
   377  		break;
   378  
   379  	case OADDR:
   380  		agen(nl, res);
   381  		break;
   382  
   383  	case OCALLMETH:
   384  		cgen_callmeth(n, 0);
   385  		cgen_callret(n, res);
   386  		break;
   387  
   388  	case OCALLINTER:
   389  		cgen_callinter(n, res, 0);
   390  		cgen_callret(n, res);
   391  		break;
   392  
   393  	case OCALLFUNC:
   394  		cgen_call(n, 0);
   395  		cgen_callret(n, res);
   396  		break;
   397  
   398  	case OMOD:
   399  	case ODIV:
   400  		cgen_div(n->op, nl, nr, res);
   401  		break;
   402  
   403  	case OLSH:
   404  	case ORSH:
   405  	case OLROT:
   406  		cgen_shift(n->op, n->bounded, nl, nr, res);
   407  		break;
   408  	}
   409  	return;
   410  
   411  sbop:	// symmetric binary
   412  	if(nl->ullman < nr->ullman || nl->op == OLITERAL) {
   413  		r = nl;
   414  		nl = nr;
   415  		nr = r;
   416  	}
   417  
   418  abop:	// asymmetric binary
   419  	if(smallintconst(nr)) {
   420  		mgen(nl, &n1, res);
   421  		regalloc(&n2, nl->type, &n1);
   422  		gmove(&n1, &n2);
   423  		gins(a, nr, &n2);
   424  		gmove(&n2, res);
   425  		regfree(&n2);
   426  		mfree(&n1);
   427  	} else if(nl->ullman >= nr->ullman) {
   428  		tempname(&nt, nl->type);
   429  		cgen(nl, &nt);
   430  		mgen(nr, &n2, N);
   431  		regalloc(&n1, nl->type, res);
   432  		gmove(&nt, &n1);
   433  		gins(a, &n2, &n1);
   434  		gmove(&n1, res);
   435  		regfree(&n1);
   436  		mfree(&n2);
   437  	} else {
   438  		regalloc(&n2, nr->type, res);
   439  		cgen(nr, &n2);
   440  		regalloc(&n1, nl->type, N);
   441  		cgen(nl, &n1);
   442  		gins(a, &n2, &n1);
   443  		regfree(&n2);
   444  		gmove(&n1, res);
   445  		regfree(&n1);
   446  	}
   447  	return;
   448  
   449  uop:	// unary
   450  	tempname(&n1, nl->type);
   451  	cgen(nl, &n1);
   452  	gins(a, N, &n1);
   453  	gmove(&n1, res);
   454  	return;
   455  }
   456  
   457  /*
   458   * generate an addressable node in res, containing the value of n.
   459   * n is an array index, and might be any size; res width is <= 32-bit.
   460   * returns Prog* to patch to panic call.
   461   */
   462  static Prog*
   463  igenindex(Node *n, Node *res, int bounded)
   464  {
   465  	Node tmp, lo, hi, zero;
   466  
   467  	if(!is64(n->type)) {
   468  		if(n->addable) {
   469  			// nothing to do.
   470  			*res = *n;
   471  		} else {
   472  			tempname(res, types[TUINT32]);
   473  			cgen(n, res);
   474  		}
   475  		return nil;
   476  	}
   477  
   478  	tempname(&tmp, types[TINT64]);
   479  	cgen(n, &tmp);
   480  	split64(&tmp, &lo, &hi);
   481  	tempname(res, types[TUINT32]);
   482  	gmove(&lo, res);
   483  	if(bounded) {
   484  		splitclean();
   485  		return nil;
   486  	}
   487  	nodconst(&zero, types[TINT32], 0);
   488  	gins(ACMPL, &hi, &zero);
   489  	splitclean();
   490  	return gbranch(AJNE, T, +1);
   491  }
   492  		
   493  /*
   494   * address gen
   495   *	res = &n;
   496   * The generated code checks that the result is not nil.
   497   */
   498  void
   499  agen(Node *n, Node *res)
   500  {
   501  	Node *nl, *nr;
   502  	Node n1, n2, n3, tmp, nlen;
   503  	Type *t;
   504  	uint32 w;
   505  	uint64 v;
   506  	Prog *p1, *p2;
   507  	int bounded;
   508  
   509  	if(debug['g']) {
   510  		dump("\nagen-res", res);
   511  		dump("agen-r", n);
   512  	}
   513  	if(n == N || n->type == T || res == N || res->type == T)
   514  		fatal("agen");
   515  
   516  	while(n->op == OCONVNOP)
   517  		n = n->left;
   518  
   519  	if(isconst(n, CTNIL) && n->type->width > widthptr) {
   520  		// Use of a nil interface or nil slice.
   521  		// Create a temporary we can take the address of and read.
   522  		// The generated code is just going to panic, so it need not
   523  		// be terribly efficient. See issue 3670.
   524  		tempname(&n1, n->type);
   525  		clearfat(&n1);
   526  		regalloc(&n2, types[tptr], res);
   527  		gins(ALEAL, &n1, &n2);
   528  		gmove(&n2, res);
   529  		regfree(&n2);
   530  		return;
   531  	}
   532  		
   533  	// addressable var is easy
   534  	if(n->addable) {
   535  		if(n->op == OREGISTER)
   536  			fatal("agen OREGISTER");
   537  		regalloc(&n1, types[tptr], res);
   538  		gins(ALEAL, n, &n1);
   539  		gmove(&n1, res);
   540  		regfree(&n1);
   541  		return;
   542  	}
   543  
   544  	// let's compute
   545  	nl = n->left;
   546  	nr = n->right;
   547  
   548  	switch(n->op) {
   549  	default:
   550  		fatal("agen %O", n->op);
   551  
   552  	case OCALLMETH:
   553  		cgen_callmeth(n, 0);
   554  		cgen_aret(n, res);
   555  		break;
   556  
   557  	case OCALLINTER:
   558  		cgen_callinter(n, res, 0);
   559  		cgen_aret(n, res);
   560  		break;
   561  
   562  	case OCALLFUNC:
   563  		cgen_call(n, 0);
   564  		cgen_aret(n, res);
   565  		break;
   566  
   567  	case OSLICE:
   568  	case OSLICEARR:
   569  	case OSLICESTR:
   570  	case OSLICE3:
   571  	case OSLICE3ARR:
   572  		tempname(&n1, n->type);
   573  		cgen_slice(n, &n1);
   574  		agen(&n1, res);
   575  		break;
   576  
   577  	case OEFACE:
   578  		tempname(&n1, n->type);
   579  		cgen_eface(n, &n1);
   580  		agen(&n1, res);
   581  		break;
   582  
   583  	case OINDEX:
   584  		p2 = nil;  // to be patched to panicindex.
   585  		w = n->type->width;
   586  		bounded = debug['B'] || n->bounded;
   587  		if(nr->addable) {
   588  			// Generate &nl first, and move nr into register.
   589  			if(!isconst(nl, CTSTR))
   590  				igen(nl, &n3, res);
   591  			if(!isconst(nr, CTINT)) {
   592  				p2 = igenindex(nr, &tmp, bounded);
   593  				regalloc(&n1, tmp.type, N);
   594  				gmove(&tmp, &n1);
   595  			}
   596  		} else if(nl->addable) {
   597  			// Generate nr first, and move &nl into register.
   598  			if(!isconst(nr, CTINT)) {
   599  				p2 = igenindex(nr, &tmp, bounded);
   600  				regalloc(&n1, tmp.type, N);
   601  				gmove(&tmp, &n1);
   602  			}
   603  			if(!isconst(nl, CTSTR))
   604  				igen(nl, &n3, res);
   605  		} else {
   606  			p2 = igenindex(nr, &tmp, bounded);
   607  			nr = &tmp;
   608  			if(!isconst(nl, CTSTR))
   609  				igen(nl, &n3, res);
   610  			regalloc(&n1, tmp.type, N);
   611  			gins(optoas(OAS, tmp.type), &tmp, &n1);
   612  		}
   613  
   614  		// For fixed array we really want the pointer in n3.
   615  		if(isfixedarray(nl->type)) {
   616  			regalloc(&n2, types[tptr], &n3);
   617  			agen(&n3, &n2);
   618  			regfree(&n3);
   619  			n3 = n2;
   620  		}
   621  
   622  		// &a[0] is in n3 (allocated in res)
   623  		// i is in n1 (if not constant)
   624  		// len(a) is in nlen (if needed)
   625  		// w is width
   626  
   627  		// constant index
   628  		if(isconst(nr, CTINT)) {
   629  			if(isconst(nl, CTSTR))
   630  				fatal("constant string constant index");  // front end should handle
   631  			v = mpgetfix(nr->val.u.xval);
   632  			if(isslice(nl->type) || nl->type->etype == TSTRING) {
   633  				if(!debug['B'] && !n->bounded) {
   634  					nlen = n3;
   635  					nlen.type = types[TUINT32];
   636  					nlen.xoffset += Array_nel;
   637  					nodconst(&n2, types[TUINT32], v);
   638  					gins(optoas(OCMP, types[TUINT32]), &nlen, &n2);
   639  					p1 = gbranch(optoas(OGT, types[TUINT32]), T, +1);
   640  					ginscall(panicindex, -1);
   641  					patch(p1, pc);
   642  				}
   643  			}
   644  
   645  			// Load base pointer in n2 = n3.
   646  			regalloc(&n2, types[tptr], &n3);
   647  			n3.type = types[tptr];
   648  			n3.xoffset += Array_array;
   649  			gmove(&n3, &n2);
   650  			regfree(&n3);
   651  			if (v*w != 0) {
   652  				nodconst(&n1, types[tptr], v*w);
   653  				gins(optoas(OADD, types[tptr]), &n1, &n2);
   654  			}
   655  			gmove(&n2, res);
   656  			regfree(&n2);
   657  			break;
   658  		}
   659  
   660  		// i is in register n1, extend to 32 bits.
   661  		t = types[TUINT32];
   662  		if(issigned[n1.type->etype])
   663  			t = types[TINT32];
   664  
   665  		regalloc(&n2, t, &n1);			// i
   666  		gmove(&n1, &n2);
   667  		regfree(&n1);
   668  
   669  		if(!debug['B'] && !n->bounded) {
   670  			// check bounds
   671  			t = types[TUINT32];
   672  			if(isconst(nl, CTSTR)) {
   673  				nodconst(&nlen, t, nl->val.u.sval->len);
   674  			} else if(isslice(nl->type) || nl->type->etype == TSTRING) {
   675  				nlen = n3;
   676  				nlen.type = t;
   677  				nlen.xoffset += Array_nel;
   678  			} else {
   679  				nodconst(&nlen, t, nl->type->bound);
   680  			}
   681  			gins(optoas(OCMP, t), &n2, &nlen);
   682  			p1 = gbranch(optoas(OLT, t), T, +1);
   683  			if(p2)
   684  				patch(p2, pc);
   685  			ginscall(panicindex, -1);
   686  			patch(p1, pc);
   687  		}
   688  
   689  		if(isconst(nl, CTSTR)) {
   690  			regalloc(&n3, types[tptr], res);
   691  			p1 = gins(ALEAL, N, &n3);
   692  			datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
   693  			p1->from.scale = 1;
   694  			p1->from.index = n2.val.u.reg;
   695  			goto indexdone;
   696  		}
   697  
   698  		// Load base pointer in n3.
   699  		regalloc(&tmp, types[tptr], &n3);
   700  		if(isslice(nl->type) || nl->type->etype == TSTRING) {
   701  			n3.type = types[tptr];
   702  			n3.xoffset += Array_array;
   703  			gmove(&n3, &tmp);
   704  		}
   705  		regfree(&n3);
   706  		n3 = tmp;
   707  
   708  		if(w == 0) {
   709  			// nothing to do
   710  		} else if(w == 1 || w == 2 || w == 4 || w == 8) {
   711  			// LEAL (n3)(n2*w), n3
   712  			p1 = gins(ALEAL, &n2, &n3);
   713  			p1->from.scale = w;
   714  			p1->from.index = p1->from.type;
   715  			p1->from.type = p1->to.type + D_INDIR;
   716  		} else {
   717  			nodconst(&tmp, types[TUINT32], w);
   718  			gins(optoas(OMUL, types[TUINT32]), &tmp, &n2);
   719  			gins(optoas(OADD, types[tptr]), &n2, &n3);
   720  		}
   721  
   722  	indexdone:
   723  		gmove(&n3, res);
   724  		regfree(&n2);
   725  		regfree(&n3);
   726  		break;
   727  
   728  	case ONAME:
   729  		// should only get here with names in this func.
   730  		if(n->funcdepth > 0 && n->funcdepth != funcdepth) {
   731  			dump("bad agen", n);
   732  			fatal("agen: bad ONAME funcdepth %d != %d",
   733  				n->funcdepth, funcdepth);
   734  		}
   735  
   736  		// should only get here for heap vars or paramref
   737  		if(!(n->class & PHEAP) && n->class != PPARAMREF) {
   738  			dump("bad agen", n);
   739  			fatal("agen: bad ONAME class %#x", n->class);
   740  		}
   741  		cgen(n->heapaddr, res);
   742  		if(n->xoffset != 0) {
   743  			nodconst(&n1, types[tptr], n->xoffset);
   744  			gins(optoas(OADD, types[tptr]), &n1, res);
   745  		}
   746  		break;
   747  
   748  	case OIND:
   749  		cgen(nl, res);
   750  		cgen_checknil(res);
   751  		break;
   752  
   753  	case ODOT:
   754  		agen(nl, res);
   755  		if(n->xoffset != 0) {
   756  			nodconst(&n1, types[tptr], n->xoffset);
   757  			gins(optoas(OADD, types[tptr]), &n1, res);
   758  		}
   759  		break;
   760  
   761  	case ODOTPTR:
   762  		t = nl->type;
   763  		if(!isptr[t->etype])
   764  			fatal("agen: not ptr %N", n);
   765  		cgen(nl, res);
   766  		cgen_checknil(res);
   767  		if(n->xoffset != 0) {
   768  			nodconst(&n1, types[tptr], n->xoffset);
   769  			gins(optoas(OADD, types[tptr]), &n1, res);
   770  		}
   771  		break;
   772  	}
   773  }
   774  
   775  /*
   776   * generate:
   777   *	newreg = &n;
   778   *	res = newreg
   779   *
   780   * on exit, a has been changed to be *newreg.
   781   * caller must regfree(a).
   782   * The generated code checks that the result is not *nil.
   783   */
   784  void
   785  igen(Node *n, Node *a, Node *res)
   786  {
   787  	Type *fp;
   788  	Iter flist;
   789  	Node n1;
   790  
   791  	if(debug['g']) {
   792  		dump("\nigen-n", n);
   793  	}
   794  	switch(n->op) {
   795  	case ONAME:
   796  		if((n->class&PHEAP) || n->class == PPARAMREF)
   797  			break;
   798  		*a = *n;
   799  		return;
   800  
   801  	case OINDREG:
   802  		// Increase the refcount of the register so that igen's caller
   803  		// has to call regfree.
   804  		if(n->val.u.reg != D_SP)
   805  			reg[n->val.u.reg]++;
   806  		*a = *n;
   807  		return;
   808  
   809  	case ODOT:
   810  		igen(n->left, a, res);
   811  		a->xoffset += n->xoffset;
   812  		a->type = n->type;
   813  		return;
   814  
   815  	case ODOTPTR:
   816  		switch(n->left->op) {
   817  		case ODOT:
   818  		case ODOTPTR:
   819  		case OCALLFUNC:
   820  		case OCALLMETH:
   821  		case OCALLINTER:
   822  			// igen-able nodes.
   823  			igen(n->left, &n1, res);
   824  			regalloc(a, types[tptr], &n1);
   825  			gmove(&n1, a);
   826  			regfree(&n1);
   827  			break;
   828  		default:
   829  			regalloc(a, types[tptr], res);
   830  			cgen(n->left, a);
   831  		}
   832  		cgen_checknil(a);
   833  		a->op = OINDREG;
   834  		a->xoffset += n->xoffset;
   835  		a->type = n->type;
   836  		return;
   837  
   838  	case OCALLFUNC:
   839  	case OCALLMETH:
   840  	case OCALLINTER:
   841  		switch(n->op) {
   842  		case OCALLFUNC:
   843  			cgen_call(n, 0);
   844  			break;
   845  		case OCALLMETH:
   846  			cgen_callmeth(n, 0);
   847  			break;
   848  		case OCALLINTER:
   849  			cgen_callinter(n, N, 0);
   850  			break;
   851  		}
   852  		fp = structfirst(&flist, getoutarg(n->left->type));
   853  		memset(a, 0, sizeof *a);
   854  		a->op = OINDREG;
   855  		a->val.u.reg = D_SP;
   856  		a->addable = 1;
   857  		a->xoffset = fp->width;
   858  		a->type = n->type;
   859  		return;
   860  
   861  	case OINDEX:
   862  		// Index of fixed-size array by constant can
   863  		// put the offset in the addressing.
   864  		// Could do the same for slice except that we need
   865  		// to use the real index for the bounds checking.
   866  		if(isfixedarray(n->left->type) ||
   867  		   (isptr[n->left->type->etype] && isfixedarray(n->left->left->type)))
   868  		if(isconst(n->right, CTINT)) {
   869  			// Compute &a.
   870  			if(!isptr[n->left->type->etype])
   871  				igen(n->left, a, res);
   872  			else {
   873  				igen(n->left, &n1, res);
   874  				cgen_checknil(&n1);
   875  				regalloc(a, types[tptr], res);
   876  				gmove(&n1, a);
   877  				regfree(&n1);
   878  				a->op = OINDREG;
   879  			}
   880  
   881  			// Compute &a[i] as &a + i*width.
   882  			a->type = n->type;
   883  			a->xoffset += mpgetfix(n->right->val.u.xval)*n->type->width;
   884  			return;
   885  		}
   886  		break;
   887  	}
   888  
   889  	// release register for now, to avoid
   890  	// confusing tempname.
   891  	if(res != N && res->op == OREGISTER)
   892  		reg[res->val.u.reg]--;
   893  	tempname(&n1, types[tptr]);
   894  	agen(n, &n1);
   895  	if(res != N && res->op == OREGISTER)
   896  		reg[res->val.u.reg]++;
   897  	regalloc(a, types[tptr], res);
   898  	gmove(&n1, a);
   899  	a->op = OINDREG;
   900  	a->type = n->type;
   901  }
   902  
   903  /*
   904   * branch gen
   905   *	if(n == true) goto to;
   906   */
   907  void
   908  bgen(Node *n, int true, int likely, Prog *to)
   909  {
   910  	int et, a;
   911  	Node *nl, *nr, *r;
   912  	Node n1, n2, tmp;
   913  	Prog *p1, *p2;
   914  
   915  	if(debug['g']) {
   916  		dump("\nbgen", n);
   917  	}
   918  
   919  	if(n == N)
   920  		n = nodbool(1);
   921  
   922  	if(n->ninit != nil)
   923  		genlist(n->ninit);
   924  
   925  	if(n->type == T) {
   926  		convlit(&n, types[TBOOL]);
   927  		if(n->type == T)
   928  			return;
   929  	}
   930  
   931  	et = n->type->etype;
   932  	if(et != TBOOL) {
   933  		yyerror("cgen: bad type %T for %O", n->type, n->op);
   934  		patch(gins(AEND, N, N), to);
   935  		return;
   936  	}
   937  	nl = n->left;
   938  	nr = N;
   939  
   940  	if(nl != N && isfloat[nl->type->etype]) {
   941  		bgen_float(n, true, likely, to);
   942  		return;
   943  	}
   944  
   945  	switch(n->op) {
   946  	default:
   947  	def:
   948  		regalloc(&n1, n->type, N);
   949  		cgen(n, &n1);
   950  		nodconst(&n2, n->type, 0);
   951  		gins(optoas(OCMP, n->type), &n1, &n2);
   952  		a = AJNE;
   953  		if(!true)
   954  			a = AJEQ;
   955  		patch(gbranch(a, n->type, likely), to);
   956  		regfree(&n1);
   957  		return;
   958  
   959  	case OLITERAL:
   960  		// need to ask if it is bool?
   961  		if(!true == !n->val.u.bval)
   962  			patch(gbranch(AJMP, T, 0), to);
   963  		return;
   964  
   965  	case ONAME:
   966  		if(!n->addable)
   967  			goto def;
   968  		nodconst(&n1, n->type, 0);
   969  		gins(optoas(OCMP, n->type), n, &n1);
   970  		a = AJNE;
   971  		if(!true)
   972  			a = AJEQ;
   973  		patch(gbranch(a, n->type, likely), to);
   974  		return;
   975  
   976  	case OANDAND:
   977  		if(!true)
   978  			goto caseor;
   979  
   980  	caseand:
   981  		p1 = gbranch(AJMP, T, 0);
   982  		p2 = gbranch(AJMP, T, 0);
   983  		patch(p1, pc);
   984  		bgen(n->left, !true, -likely, p2);
   985  		bgen(n->right, !true, -likely, p2);
   986  		p1 = gbranch(AJMP, T, 0);
   987  		patch(p1, to);
   988  		patch(p2, pc);
   989  		return;
   990  
   991  	case OOROR:
   992  		if(!true)
   993  			goto caseand;
   994  
   995  	caseor:
   996  		bgen(n->left, true, likely, to);
   997  		bgen(n->right, true, likely, to);
   998  		return;
   999  
  1000  	case OEQ:
  1001  	case ONE:
  1002  	case OLT:
  1003  	case OGT:
  1004  	case OLE:
  1005  	case OGE:
  1006  		nr = n->right;
  1007  		if(nr == N || nr->type == T)
  1008  			return;
  1009  
  1010  	case ONOT:	// unary
  1011  		nl = n->left;
  1012  		if(nl == N || nl->type == T)
  1013  			return;
  1014  	}
  1015  
  1016  	switch(n->op) {
  1017  	case ONOT:
  1018  		bgen(nl, !true, likely, to);
  1019  		break;
  1020  
  1021  	case OEQ:
  1022  	case ONE:
  1023  	case OLT:
  1024  	case OGT:
  1025  	case OLE:
  1026  	case OGE:
  1027  		a = n->op;
  1028  		if(!true) {
  1029  			a = brcom(a);
  1030  			true = !true;
  1031  		}
  1032  
  1033  		// make simplest on right
  1034  		if(nl->op == OLITERAL || (nl->ullman < nr->ullman && nl->ullman < UINF)) {
  1035  			a = brrev(a);
  1036  			r = nl;
  1037  			nl = nr;
  1038  			nr = r;
  1039  		}
  1040  
  1041  		if(isslice(nl->type)) {
  1042  			// front end should only leave cmp to literal nil
  1043  			if((a != OEQ && a != ONE) || nr->op != OLITERAL) {
  1044  				yyerror("illegal slice comparison");
  1045  				break;
  1046  			}
  1047  			a = optoas(a, types[tptr]);
  1048  			igen(nl, &n1, N);
  1049  			n1.xoffset += Array_array;
  1050  			n1.type = types[tptr];
  1051  			nodconst(&tmp, types[tptr], 0);
  1052  			gins(optoas(OCMP, types[tptr]), &n1, &tmp);
  1053  			patch(gbranch(a, types[tptr], likely), to);
  1054  			regfree(&n1);
  1055  			break;
  1056  		}
  1057  
  1058  		if(isinter(nl->type)) {
  1059  			// front end should only leave cmp to literal nil
  1060  			if((a != OEQ && a != ONE) || nr->op != OLITERAL) {
  1061  				yyerror("illegal interface comparison");
  1062  				break;
  1063  			}
  1064  			a = optoas(a, types[tptr]);
  1065  			igen(nl, &n1, N);
  1066  			n1.type = types[tptr];
  1067  			nodconst(&tmp, types[tptr], 0);
  1068  			gins(optoas(OCMP, types[tptr]), &n1, &tmp);
  1069  			patch(gbranch(a, types[tptr], likely), to);
  1070  			regfree(&n1);
  1071  			break;
  1072  		}
  1073  
  1074  		if(iscomplex[nl->type->etype]) {
  1075  			complexbool(a, nl, nr, true, likely, to);
  1076  			break;
  1077  		}
  1078  
  1079  		if(is64(nr->type)) {
  1080  			if(!nl->addable || isconst(nl, CTINT)) {
  1081  				tempname(&n1, nl->type);
  1082  				cgen(nl, &n1);
  1083  				nl = &n1;
  1084  			}
  1085  			if(!nr->addable) {
  1086  				tempname(&n2, nr->type);
  1087  				cgen(nr, &n2);
  1088  				nr = &n2;
  1089  			}
  1090  			cmp64(nl, nr, a, likely, to);
  1091  			break;
  1092  		}
  1093  
  1094  		if(nr->ullman >= UINF) {
  1095  			if(!nl->addable) {
  1096  				tempname(&n1, nl->type);
  1097  				cgen(nl, &n1);
  1098  				nl = &n1;
  1099  			}
  1100  			if(!nr->addable) {
  1101  				tempname(&tmp, nr->type);
  1102  				cgen(nr, &tmp);
  1103  				nr = &tmp;
  1104  			}
  1105  			regalloc(&n2, nr->type, N);
  1106  			cgen(nr, &n2);
  1107  			nr = &n2;
  1108  			goto cmp;
  1109  		}
  1110  
  1111  		if(!nl->addable) {
  1112  			tempname(&n1, nl->type);
  1113  			cgen(nl, &n1);
  1114  			nl = &n1;
  1115  		}
  1116  
  1117  		if(smallintconst(nr)) {
  1118  			gins(optoas(OCMP, nr->type), nl, nr);
  1119  			patch(gbranch(optoas(a, nr->type), nr->type, likely), to);
  1120  			break;
  1121  		}
  1122  
  1123  		if(!nr->addable) {
  1124  			tempname(&tmp, nr->type);
  1125  			cgen(nr, &tmp);
  1126  			nr = &tmp;
  1127  		}
  1128  		regalloc(&n2, nr->type, N);
  1129  		gmove(nr, &n2);
  1130  		nr = &n2;
  1131  
  1132  cmp:
  1133  		gins(optoas(OCMP, nr->type), nl, nr);
  1134  		patch(gbranch(optoas(a, nr->type), nr->type, likely), to);
  1135  
  1136  		if(nl->op == OREGISTER)
  1137  			regfree(nl);
  1138  		regfree(nr);
  1139  		break;
  1140  	}
  1141  }
  1142  
  1143  /*
  1144   * n is on stack, either local variable
  1145   * or return value from function call.
  1146   * return n's offset from SP.
  1147   */
  1148  int32
  1149  stkof(Node *n)
  1150  {
  1151  	Type *t;
  1152  	Iter flist;
  1153  	int32 off;
  1154  
  1155  	switch(n->op) {
  1156  	case OINDREG:
  1157  		return n->xoffset;
  1158  
  1159  	case ODOT:
  1160  		t = n->left->type;
  1161  		if(isptr[t->etype])
  1162  			break;
  1163  		off = stkof(n->left);
  1164  		if(off == -1000 || off == 1000)
  1165  			return off;
  1166  		return off + n->xoffset;
  1167  
  1168  	case OINDEX:
  1169  		t = n->left->type;
  1170  		if(!isfixedarray(t))
  1171  			break;
  1172  		off = stkof(n->left);
  1173  		if(off == -1000 || off == 1000)
  1174  			return off;
  1175  		if(isconst(n->right, CTINT))
  1176  			return off + t->type->width * mpgetfix(n->right->val.u.xval);
  1177  		return 1000;
  1178  		
  1179  	case OCALLMETH:
  1180  	case OCALLINTER:
  1181  	case OCALLFUNC:
  1182  		t = n->left->type;
  1183  		if(isptr[t->etype])
  1184  			t = t->type;
  1185  
  1186  		t = structfirst(&flist, getoutarg(t));
  1187  		if(t != T)
  1188  			return t->width;
  1189  		break;
  1190  	}
  1191  
  1192  	// botch - probably failing to recognize address
  1193  	// arithmetic on the above. eg INDEX and DOT
  1194  	return -1000;
  1195  }
  1196  
  1197  /*
  1198   * struct gen
  1199   *	memmove(&res, &n, w);
  1200   */
  1201  void
  1202  sgen(Node *n, Node *res, int64 w)
  1203  {
  1204  	Node dst, src, tdst, tsrc;
  1205  	int32 c, q, odst, osrc;
  1206  
  1207  	if(debug['g']) {
  1208  		print("\nsgen w=%lld\n", w);
  1209  		dump("r", n);
  1210  		dump("res", res);
  1211  	}
  1212  	if(n->ullman >= UINF && res->ullman >= UINF)
  1213  		fatal("sgen UINF");
  1214  
  1215  	if(w < 0 || (int32)w != w)
  1216  		fatal("sgen copy %lld", w);
  1217  
  1218  	if(w == 0) {
  1219  		// evaluate side effects only.
  1220  		tempname(&tdst, types[tptr]);
  1221  		agen(res, &tdst);
  1222  		agen(n, &tdst);
  1223  		return;
  1224  	}
  1225  
  1226  	// Avoid taking the address for simple enough types.
  1227  	if(componentgen(n, res))
  1228  		return;
  1229  
  1230  	// offset on the stack
  1231  	osrc = stkof(n);
  1232  	odst = stkof(res);
  1233  	
  1234  	if(osrc != -1000 && odst != -1000 && (osrc == 1000 || odst == 1000)) {
  1235  		// osrc and odst both on stack, and at least one is in
  1236  		// an unknown position.  Could generate code to test
  1237  		// for forward/backward copy, but instead just copy
  1238  		// to a temporary location first.
  1239  		tempname(&tsrc, n->type);
  1240  		sgen(n, &tsrc, w);
  1241  		sgen(&tsrc, res, w);
  1242  		return;
  1243  	}
  1244  
  1245  	nodreg(&dst, types[tptr], D_DI);
  1246  	nodreg(&src, types[tptr], D_SI);
  1247  
  1248  	tempname(&tsrc, types[tptr]);
  1249  	tempname(&tdst, types[tptr]);
  1250  	if(!n->addable)
  1251  		agen(n, &tsrc);
  1252  	if(!res->addable)
  1253  		agen(res, &tdst);
  1254  	if(n->addable)
  1255  		agen(n, &src);
  1256  	else
  1257  		gmove(&tsrc, &src);
  1258  	if(res->addable)
  1259  		agen(res, &dst);
  1260  	else
  1261  		gmove(&tdst, &dst);
  1262  
  1263  	c = w % 4;	// bytes
  1264  	q = w / 4;	// doublewords
  1265  
  1266  	// if we are copying forward on the stack and
  1267  	// the src and dst overlap, then reverse direction
  1268  	if(osrc < odst && odst < osrc+w) {
  1269  		// reverse direction
  1270  		gins(ASTD, N, N);		// set direction flag
  1271  		if(c > 0) {
  1272  			gconreg(AADDL, w-1, D_SI);
  1273  			gconreg(AADDL, w-1, D_DI);
  1274  
  1275  			gconreg(AMOVL, c, D_CX);
  1276  			gins(AREP, N, N);	// repeat
  1277  			gins(AMOVSB, N, N);	// MOVB *(SI)-,*(DI)-
  1278  		}
  1279  
  1280  		if(q > 0) {
  1281  			if(c > 0) {
  1282  				gconreg(AADDL, -3, D_SI);
  1283  				gconreg(AADDL, -3, D_DI);
  1284  			} else {
  1285  				gconreg(AADDL, w-4, D_SI);
  1286  				gconreg(AADDL, w-4, D_DI);
  1287  			}
  1288  			gconreg(AMOVL, q, D_CX);
  1289  			gins(AREP, N, N);	// repeat
  1290  			gins(AMOVSL, N, N);	// MOVL *(SI)-,*(DI)-
  1291  		}
  1292  		// we leave with the flag clear
  1293  		gins(ACLD, N, N);
  1294  	} else {
  1295  		gins(ACLD, N, N);	// paranoia.  TODO(rsc): remove?
  1296  		// normal direction
  1297  		if(q >= 4) {
  1298  			gconreg(AMOVL, q, D_CX);
  1299  			gins(AREP, N, N);	// repeat
  1300  			gins(AMOVSL, N, N);	// MOVL *(SI)+,*(DI)+
  1301  		} else
  1302  		while(q > 0) {
  1303  			gins(AMOVSL, N, N);	// MOVL *(SI)+,*(DI)+
  1304  			q--;
  1305  		}
  1306  		while(c > 0) {
  1307  			gins(AMOVSB, N, N);	// MOVB *(SI)+,*(DI)+
  1308  			c--;
  1309  		}
  1310  	}
  1311  }
  1312  
  1313  static int
  1314  cadable(Node *n)
  1315  {
  1316  	if(!n->addable) {
  1317  		// dont know how it happens,
  1318  		// but it does
  1319  		return 0;
  1320  	}
  1321  
  1322  	switch(n->op) {
  1323  	case ONAME:
  1324  		return 1;
  1325  	}
  1326  	return 0;
  1327  }
  1328  
  1329  /*
  1330   * copy a composite value by moving its individual components.
  1331   * Slices, strings and interfaces are supported.
  1332   * nr is N when assigning a zero value.
  1333   * return 1 if can do, 0 if can't.
  1334   */
  1335  int
  1336  componentgen(Node *nr, Node *nl)
  1337  {
  1338  	Node nodl, nodr;
  1339  	int freel, freer;
  1340  
  1341  	freel = 0;
  1342  	freer = 0;
  1343  
  1344  	switch(nl->type->etype) {
  1345  	default:
  1346  		goto no;
  1347  
  1348  	case TARRAY:
  1349  		if(!isslice(nl->type))
  1350  			goto no;
  1351  	case TSTRING:
  1352  	case TINTER:
  1353  		break;
  1354  	}
  1355  
  1356  	nodl = *nl;
  1357  	if(!cadable(nl)) {
  1358  		if(nr == N || !cadable(nr))
  1359  			goto no;
  1360  		igen(nl, &nodl, N);
  1361  		freel = 1;
  1362  	}
  1363  
  1364  	if(nr != N) {
  1365  		nodr = *nr;
  1366  		if(!cadable(nr)) {
  1367  			igen(nr, &nodr, N);
  1368  			freer = 1;
  1369  		}
  1370  	}
  1371  
  1372  	switch(nl->type->etype) {
  1373  	case TARRAY:
  1374  		nodl.xoffset += Array_array;
  1375  		nodl.type = ptrto(nl->type->type);
  1376  
  1377  		if(nr != N) {
  1378  			nodr.xoffset += Array_array;
  1379  			nodr.type = nodl.type;
  1380  		} else
  1381  			nodconst(&nodr, nodl.type, 0);
  1382  		gmove(&nodr, &nodl);
  1383  
  1384  		nodl.xoffset += Array_nel-Array_array;
  1385  		nodl.type = types[TUINT32];
  1386  
  1387  		if(nr != N) {
  1388  			nodr.xoffset += Array_nel-Array_array;
  1389  			nodr.type = nodl.type;
  1390  		} else
  1391  			nodconst(&nodr, nodl.type, 0);
  1392  		gmove(&nodr, &nodl);
  1393  
  1394  		nodl.xoffset += Array_cap-Array_nel;
  1395  		nodl.type = types[TUINT32];
  1396  
  1397  		if(nr != N) {
  1398  			nodr.xoffset += Array_cap-Array_nel;
  1399  			nodr.type = nodl.type;
  1400  		} else
  1401  			nodconst(&nodr, nodl.type, 0);
  1402  		gmove(&nodr, &nodl);
  1403  
  1404  		goto yes;
  1405  
  1406  	case TSTRING:
  1407  		nodl.xoffset += Array_array;
  1408  		nodl.type = ptrto(types[TUINT8]);
  1409  
  1410  		if(nr != N) {
  1411  			nodr.xoffset += Array_array;
  1412  			nodr.type = nodl.type;
  1413  		} else
  1414  			nodconst(&nodr, nodl.type, 0);
  1415  		gmove(&nodr, &nodl);
  1416  
  1417  		nodl.xoffset += Array_nel-Array_array;
  1418  		nodl.type = types[TUINT32];
  1419  
  1420  		if(nr != N) {
  1421  			nodr.xoffset += Array_nel-Array_array;
  1422  			nodr.type = nodl.type;
  1423  		} else
  1424  			nodconst(&nodr, nodl.type, 0);
  1425  		gmove(&nodr, &nodl);
  1426  
  1427  		goto yes;
  1428  
  1429  	case TINTER:
  1430  		nodl.xoffset += Array_array;
  1431  		nodl.type = ptrto(types[TUINT8]);
  1432  
  1433  		if(nr != N) {
  1434  			nodr.xoffset += Array_array;
  1435  			nodr.type = nodl.type;
  1436  		} else
  1437  			nodconst(&nodr, nodl.type, 0);
  1438  		gmove(&nodr, &nodl);
  1439  
  1440  		nodl.xoffset += Array_nel-Array_array;
  1441  		nodl.type = ptrto(types[TUINT8]);
  1442  
  1443  		if(nr != N) {
  1444  			nodr.xoffset += Array_nel-Array_array;
  1445  			nodr.type = nodl.type;
  1446  		} else
  1447  			nodconst(&nodr, nodl.type, 0);
  1448  		gmove(&nodr, &nodl);
  1449  
  1450  		goto yes;
  1451  	}
  1452  
  1453  no:
  1454  	if(freer)
  1455  		regfree(&nodr);
  1456  	if(freel)
  1457  		regfree(&nodl);
  1458  	return 0;
  1459  
  1460  yes:
  1461  	if(freer)
  1462  		regfree(&nodr);
  1463  	if(freel)
  1464  		regfree(&nodl);
  1465  	return 1;
  1466  }