github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/5g/gsubr.c (about)

     1  // Derived from Inferno utils/5c/txt.c
     2  // http://code.google.com/p/inferno-os/source/browse/utils/5c/txt.c
     3  //
     4  //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
     5  //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
     6  //	Portions Copyright © 1997-1999 Vita Nuova Limited
     7  //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
     8  //	Portions Copyright © 2004,2006 Bruce Ellis
     9  //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    10  //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    11  //	Portions Copyright © 2009 The Go Authors.  All rights reserved.
    12  //
    13  // Permission is hereby granted, free of charge, to any person obtaining a copy
    14  // of this software and associated documentation files (the "Software"), to deal
    15  // in the Software without restriction, including without limitation the rights
    16  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    17  // copies of the Software, and to permit persons to whom the Software is
    18  // furnished to do so, subject to the following conditions:
    19  //
    20  // The above copyright notice and this permission notice shall be included in
    21  // all copies or substantial portions of the Software.
    22  //
    23  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    24  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    25  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    26  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    27  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    28  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    29  // THE SOFTWARE.
    30  
    31  #include <u.h>
    32  #include <libc.h>
    33  #include "gg.h"
    34  
    35  // TODO(kaib): Can make this bigger if we move
    36  // the text segment up higher in 5l for all GOOS.
    37  long unmappedzero = 4096;
    38  
    39  void
    40  clearp(Prog *p)
    41  {
    42  	p->as = AEND;
    43  	p->reg = NREG;
    44  	p->scond = C_SCOND_NONE;
    45  	p->from.type = D_NONE;
    46  	p->from.name = D_NONE;
    47  	p->from.reg = NREG;
    48  	p->to.type = D_NONE;
    49  	p->to.name = D_NONE;
    50  	p->to.reg = NREG;
    51  	p->loc = pcloc;
    52  	pcloc++;
    53  }
    54  
    55  static int ddumped;
    56  static Prog *dfirst;
    57  static Prog *dpc;
    58  
    59  /*
    60   * generate and return proc with p->as = as,
    61   * linked into program.  pc is next instruction.
    62   */
    63  Prog*
    64  prog(int as)
    65  {
    66  	Prog *p;
    67  
    68  	if(as == ADATA || as == AGLOBL) {
    69  		if(ddumped)
    70  			fatal("already dumped data");
    71  		if(dpc == nil) {
    72  			dpc = mal(sizeof(*dpc));
    73  			dfirst = dpc;
    74  		}
    75  		p = dpc;
    76  		dpc = mal(sizeof(*dpc));
    77  		p->link = dpc;
    78  		p->reg = 0;  // used for flags
    79  	} else {
    80  		p = pc;
    81  		pc = mal(sizeof(*pc));
    82  		clearp(pc);
    83  		p->link = pc;
    84  	}
    85  
    86  	if(lineno == 0) {
    87  		if(debug['K'])
    88  			warn("prog: line 0");
    89  	}
    90  
    91  	p->as = as;
    92  	p->lineno = lineno;
    93  	return p;
    94  }
    95  
    96  void
    97  dumpdata(void)
    98  {
    99  	ddumped = 1;
   100  	if(dfirst == nil)
   101  		return;
   102  	newplist();
   103  	*pc = *dfirst;
   104  	pc = dpc;
   105  	clearp(pc);
   106  }
   107  
   108  /*
   109   * generate a branch.
   110   * t is ignored.
   111   * likely values are for branch prediction:
   112   *	-1 unlikely
   113   *	0 no opinion
   114   *	+1 likely
   115   */
   116  Prog*
   117  gbranch(int as, Type *t, int likely)
   118  {
   119  	Prog *p;
   120  
   121  	USED(t);
   122  	USED(likely);  // TODO: record this for linker
   123  
   124  	p = prog(as);
   125  	p->to.type = D_BRANCH;
   126  	p->to.u.branch = P;
   127  	return p;
   128  }
   129  
   130  /*
   131   * patch previous branch to jump to to.
   132   */
   133  void
   134  patch(Prog *p, Prog *to)
   135  {
   136  	if(p->to.type != D_BRANCH)
   137  		fatal("patch: not a branch");
   138  	p->to.u.branch = to;
   139  	p->to.offset = to->loc;
   140  }
   141  
   142  Prog*
   143  unpatch(Prog *p)
   144  {
   145  	Prog *q;
   146  
   147  	if(p->to.type != D_BRANCH)
   148  		fatal("unpatch: not a branch");
   149  	q = p->to.u.branch;
   150  	p->to.u.branch = P;
   151  	p->to.offset = 0;
   152  	return q;
   153  }
   154  
   155  /*
   156   * start a new Prog list.
   157   */
   158  Plist*
   159  newplist(void)
   160  {
   161  	Plist *pl;
   162  
   163  	pl = mal(sizeof(*pl));
   164  	if(plist == nil)
   165  		plist = pl;
   166  	else
   167  		plast->link = pl;
   168  	plast = pl;
   169  
   170  	pc = mal(sizeof(*pc));
   171  	clearp(pc);
   172  	pl->firstpc = pc;
   173  
   174  	return pl;
   175  }
   176  
   177  void
   178  gused(Node *n)
   179  {
   180  	gins(ANOP, n, N);	// used
   181  }
   182  
   183  Prog*
   184  gjmp(Prog *to)
   185  {
   186  	Prog *p;
   187  
   188  	p = gbranch(AB, T, 0);
   189  	if(to != P)
   190  		patch(p, to);
   191  	return p;
   192  }
   193  
   194  void
   195  ggloblnod(Node *nam)
   196  {
   197  	Prog *p;
   198  
   199  	p = gins(AGLOBL, nam, N);
   200  	p->lineno = nam->lineno;
   201  	p->from.gotype = ngotype(nam);
   202  	p->to.sym = S;
   203  	p->to.type = D_CONST;
   204  	p->to.offset = nam->type->width;
   205  	if(nam->readonly)
   206  		p->reg = RODATA;
   207  	if(nam->type != T && !haspointers(nam->type))
   208  		p->reg |= NOPTR;
   209  }
   210  
   211  void
   212  ggloblsym(Sym *s, int32 width, int dupok, int rodata)
   213  {
   214  	Prog *p;
   215  
   216  	p = gins(AGLOBL, N, N);
   217  	p->from.type = D_OREG;
   218  	p->from.name = D_EXTERN;
   219  	p->from.sym = s;
   220  	p->to.type = D_CONST;
   221  	p->to.name = D_NONE;
   222  	p->to.offset = width;
   223  	if(dupok)
   224  		p->reg |= DUPOK;
   225  	if(rodata)
   226  		p->reg |= RODATA;
   227  }
   228  
   229  void
   230  gtrack(Sym *s)
   231  {
   232  	Prog *p;
   233  	
   234  	p = gins(AUSEFIELD, N, N);
   235  	p->from.type = D_OREG;
   236  	p->from.name = D_EXTERN;
   237  	p->from.sym = s;
   238  }
   239  
   240  int
   241  isfat(Type *t)
   242  {
   243  	if(t != T)
   244  	switch(t->etype) {
   245  	case TSTRUCT:
   246  	case TARRAY:
   247  	case TSTRING:
   248  	case TINTER:	// maybe remove later
   249  		return 1;
   250  	}
   251  	return 0;
   252  }
   253  
   254  /*
   255   * naddr of func generates code for address of func.
   256   * if using opcode that can take address implicitly,
   257   * call afunclit to fix up the argument.
   258   * also fix up direct register references to be D_OREG.
   259   */
   260  void
   261  afunclit(Addr *a, Node *n)
   262  {
   263  	if(a->type == D_CONST && a->name == D_EXTERN || a->type == D_REG) {
   264  		a->type = D_OREG;
   265  		if(n->op == ONAME)
   266  			a->sym = n->sym;
   267  	}
   268  }
   269  
   270  static	int	resvd[] =
   271  {
   272  	9,     // reserved for m
   273  	10,    // reserved for g
   274  	REGSP, // reserved for SP
   275  };
   276  
   277  void
   278  ginit(void)
   279  {
   280  	int i;
   281  
   282  	for(i=0; i<nelem(reg); i++)
   283  		reg[i] = 0;
   284  	for(i=0; i<nelem(resvd); i++)
   285  		reg[resvd[i]]++;
   286  }
   287  
   288  void
   289  gclean(void)
   290  {
   291  	int i;
   292  
   293  	for(i=0; i<nelem(resvd); i++)
   294  		reg[resvd[i]]--;
   295  
   296  	for(i=0; i<nelem(reg); i++)
   297  		if(reg[i])
   298  			yyerror("reg %R left allocated\n", i);
   299  }
   300  
   301  int32
   302  anyregalloc(void)
   303  {
   304  	int i, j;
   305  
   306  	for(i=0; i<nelem(reg); i++) {
   307  		if(reg[i] == 0)
   308  			goto ok;
   309  		for(j=0; j<nelem(resvd); j++)
   310  			if(resvd[j] == i)
   311  				goto ok;
   312  		return 1;
   313  	ok:;
   314  	}
   315  	return 0;
   316  }
   317  
   318  uintptr regpc[REGALLOC_FMAX+1];
   319  
   320  /*
   321   * allocate register of type t, leave in n.
   322   * if o != N, o is desired fixed register.
   323   * caller must regfree(n).
   324   */
   325  void
   326  regalloc(Node *n, Type *t, Node *o)
   327  {
   328  	int i, et, fixfree, floatfree;
   329  
   330  	if(0 && debug['r']) {
   331  		fixfree = 0;
   332  		for(i=REGALLOC_R0; i<=REGALLOC_RMAX; i++)
   333  			if(reg[i] == 0)
   334  				fixfree++;
   335  		floatfree = 0;
   336  		for(i=REGALLOC_F0; i<=REGALLOC_FMAX; i++)
   337  			if(reg[i] == 0)
   338  				floatfree++;
   339  		print("regalloc fix %d float %d\n", fixfree, floatfree);
   340  	}
   341  
   342  	if(t == T)
   343  		fatal("regalloc: t nil");
   344  	et = simtype[t->etype];
   345  	if(is64(t))
   346  		fatal("regalloc: 64 bit type %T");
   347  
   348  	switch(et) {
   349  	case TINT8:
   350  	case TUINT8:
   351  	case TINT16:
   352  	case TUINT16:
   353  	case TINT32:
   354  	case TUINT32:
   355  	case TPTR32:
   356  	case TBOOL:
   357  		if(o != N && o->op == OREGISTER) {
   358  			i = o->val.u.reg;
   359  			if(i >= REGALLOC_R0 && i <= REGALLOC_RMAX)
   360  				goto out;
   361  		}
   362  		for(i=REGALLOC_R0; i<=REGALLOC_RMAX; i++)
   363  			if(reg[i] == 0) {
   364  				regpc[i] = (uintptr)getcallerpc(&n);
   365  				goto out;
   366  			}
   367  		print("registers allocated at\n");
   368  		for(i=REGALLOC_R0; i<=REGALLOC_RMAX; i++)
   369  			print("%d %p\n", i, regpc[i]);
   370  		yyerror("out of fixed registers");
   371  		goto err;
   372  
   373  	case TFLOAT32:
   374  	case TFLOAT64:
   375  		if(o != N && o->op == OREGISTER) {
   376  			i = o->val.u.reg;
   377  			if(i >= REGALLOC_F0 && i <= REGALLOC_FMAX)
   378  				goto out;
   379  		}
   380  		for(i=REGALLOC_F0; i<=REGALLOC_FMAX; i++)
   381  			if(reg[i] == 0)
   382  				goto out;
   383  		yyerror("out of floating point registers");
   384  		goto err;
   385  
   386  	case TCOMPLEX64:
   387  	case TCOMPLEX128:
   388  		tempname(n, t);
   389  		return;
   390  	}
   391  	yyerror("regalloc: unknown type %T", t);
   392  
   393  err:
   394  	nodreg(n, t, 0);
   395  	return;
   396  
   397  out:
   398  	reg[i]++;
   399  	nodreg(n, t, i);
   400  }
   401  
   402  void
   403  regfree(Node *n)
   404  {
   405  	int i, fixfree, floatfree;
   406  
   407  	if(0 && debug['r']) {
   408  		fixfree = 0;
   409  		for(i=REGALLOC_R0; i<=REGALLOC_RMAX; i++)
   410  			if(reg[i] == 0)
   411  				fixfree++;
   412  		floatfree = 0;
   413  		for(i=REGALLOC_F0; i<=REGALLOC_FMAX; i++)
   414  			if(reg[i] == 0)
   415  				floatfree++;
   416  		print("regalloc fix %d float %d\n", fixfree, floatfree);
   417  	}
   418  
   419  	if(n->op == ONAME)
   420  		return;
   421  	if(n->op != OREGISTER && n->op != OINDREG)
   422  		fatal("regfree: not a register");
   423  	i = n->val.u.reg;
   424  	if(i == REGSP)
   425  		return;
   426  	if(i < 0 || i >= nelem(reg) || i >= nelem(regpc))
   427  		fatal("regfree: reg out of range");
   428  	if(reg[i] <= 0)
   429  		fatal("regfree: reg %R not allocated", i);
   430  	reg[i]--;
   431  	if(reg[i] == 0)
   432  		regpc[i] = 0;
   433  }
   434  
   435  /*
   436   * initialize n to be register r of type t.
   437   */
   438  void
   439  nodreg(Node *n, Type *t, int r)
   440  {
   441  	if(t == T)
   442  		fatal("nodreg: t nil");
   443  
   444  	memset(n, 0, sizeof(*n));
   445  	n->op = OREGISTER;
   446  	n->addable = 1;
   447  	ullmancalc(n);
   448  	n->val.u.reg = r;
   449  	n->type = t;
   450  }
   451  
   452  /*
   453   * initialize n to be indirect of register r; n is type t.
   454   */
   455  void
   456  nodindreg(Node *n, Type *t, int r)
   457  {
   458  	nodreg(n, t, r);
   459  	n->op = OINDREG;
   460  }
   461  
   462  Node*
   463  nodarg(Type *t, int fp)
   464  {
   465  	Node *n;
   466  	Type *first;
   467  	Iter savet;
   468  
   469  	// entire argument struct, not just one arg
   470  	if(t->etype == TSTRUCT && t->funarg) {
   471  		n = nod(ONAME, N, N);
   472  		n->sym = lookup(".args");
   473  		n->type = t;
   474  		first = structfirst(&savet, &t);
   475  		if(first == nil)
   476  			fatal("nodarg: bad struct");
   477  		if(first->width == BADWIDTH)
   478  			fatal("nodarg: offset not computed for %T", t);
   479  		n->xoffset = first->width;
   480  		n->addable = 1;
   481  		goto fp;
   482  	}
   483  
   484  	if(t->etype != TFIELD)
   485  		fatal("nodarg: not field %T", t);
   486  
   487  	n = nod(ONAME, N, N);
   488  	n->type = t->type;
   489  	n->sym = t->sym;
   490  	if(t->width == BADWIDTH)
   491  		fatal("nodarg: offset not computed for %T", t);
   492  	n->xoffset = t->width;
   493  	n->addable = 1;
   494  	n->orig = t->nname;
   495  
   496  fp:
   497  	// Rewrite argument named _ to __,
   498  	// or else the assignment to _ will be
   499  	// discarded during code generation.
   500  	if(isblank(n))
   501  		n->sym = lookup("__");
   502  
   503  	switch(fp) {
   504  	default:
   505  		fatal("nodarg %T %d", t, fp);
   506  
   507  	case 0:		// output arg for calling another function
   508  		n->op = OINDREG;
   509  		n->val.u.reg = REGSP;
   510  		n->xoffset += 4;
   511  		break;
   512  
   513  	case 1:		// input arg to current function
   514  		n->class = PPARAM;
   515  		break;
   516  	}
   517  	n->typecheck = 1;
   518  	return n;
   519  }
   520  
   521  /*
   522   * return constant i node.
   523   * overwritten by next call, but useful in calls to gins.
   524   */
   525  Node*
   526  ncon(uint32 i)
   527  {
   528  	static Node n;
   529  
   530  	if(n.type == T)
   531  		nodconst(&n, types[TUINT32], 0);
   532  	mpmovecfix(n.val.u.xval, i);
   533  	return &n;
   534  }
   535  
   536  /*
   537   * Is this node a memory operand?
   538   */
   539  int
   540  ismem(Node *n)
   541  {
   542  	switch(n->op) {
   543  	case OINDREG:
   544  	case ONAME:
   545  	case OPARAM:
   546  	case OCLOSUREVAR:
   547  		return 1;
   548  	}
   549  	return 0;
   550  }
   551  
   552  Node sclean[10];
   553  int nsclean;
   554  
   555  /*
   556   * n is a 64-bit value.  fill in lo and hi to refer to its 32-bit halves.
   557   */
   558  void
   559  split64(Node *n, Node *lo, Node *hi)
   560  {
   561  	Node n1;
   562  	int64 i;
   563  
   564  	if(!is64(n->type))
   565  		fatal("split64 %T", n->type);
   566  
   567  	if(nsclean >= nelem(sclean))
   568  		fatal("split64 clean");
   569  	sclean[nsclean].op = OEMPTY;
   570  	nsclean++;
   571  	switch(n->op) {
   572  	default:
   573  		if(!dotaddable(n, &n1)) {
   574  			igen(n, &n1, N);
   575  			sclean[nsclean-1] = n1;
   576  		}
   577  		n = &n1;
   578  		goto common;
   579  	case ONAME:
   580  		if(n->class == PPARAMREF) {
   581  			cgen(n->heapaddr, &n1);
   582  			sclean[nsclean-1] = n1;
   583  			// fall through.
   584  			n = &n1;
   585  		}
   586  		goto common;
   587  	case OINDREG:
   588  	common:
   589  		*lo = *n;
   590  		*hi = *n;
   591  		lo->type = types[TUINT32];
   592  		if(n->type->etype == TINT64)
   593  			hi->type = types[TINT32];
   594  		else
   595  			hi->type = types[TUINT32];
   596  		hi->xoffset += 4;
   597  		break;
   598  
   599  	case OLITERAL:
   600  		convconst(&n1, n->type, &n->val);
   601  		i = mpgetfix(n1.val.u.xval);
   602  		nodconst(lo, types[TUINT32], (uint32)i);
   603  		i >>= 32;
   604  		if(n->type->etype == TINT64)
   605  			nodconst(hi, types[TINT32], (int32)i);
   606  		else
   607  			nodconst(hi, types[TUINT32], (uint32)i);
   608  		break;
   609  	}
   610  }
   611  
   612  void
   613  splitclean(void)
   614  {
   615  	if(nsclean <= 0)
   616  		fatal("splitclean");
   617  	nsclean--;
   618  	if(sclean[nsclean].op != OEMPTY)
   619  		regfree(&sclean[nsclean]);
   620  }
   621  
   622  #define	CASE(a,b)	(((a)<<16)|((b)<<0))
   623  
   624  void
   625  gmove(Node *f, Node *t)
   626  {
   627  	int a, ft, tt, fa, ta;
   628  	Type *cvt;
   629  	Node r1, r2, flo, fhi, tlo, thi, con;
   630  	Prog *p1;
   631  
   632  	if(debug['M'])
   633  		print("gmove %N -> %N\n", f, t);
   634  
   635  	ft = simsimtype(f->type);
   636  	tt = simsimtype(t->type);
   637  	cvt = t->type;
   638  
   639  	if(iscomplex[ft] || iscomplex[tt]) {
   640  		complexmove(f, t);
   641  		return;
   642  	}
   643  
   644  	// cannot have two memory operands;
   645  	// except 64-bit, which always copies via registers anyway.
   646  	if(!is64(f->type) && !is64(t->type) && ismem(f) && ismem(t))
   647  		goto hard;
   648  
   649  	// convert constant to desired type
   650  	if(f->op == OLITERAL) {
   651  		switch(tt) {
   652  		default:
   653  			convconst(&con, t->type, &f->val);
   654  			break;
   655  
   656  		case TINT16:
   657  		case TINT8:
   658  			convconst(&con, types[TINT32], &f->val);
   659  			regalloc(&r1, con.type, t);
   660  			gins(AMOVW, &con, &r1);
   661  			gmove(&r1, t);
   662  			regfree(&r1);
   663  			return;
   664  
   665  		case TUINT16:
   666  		case TUINT8:
   667  			convconst(&con, types[TUINT32], &f->val);
   668  			regalloc(&r1, con.type, t);
   669  			gins(AMOVW, &con, &r1);
   670  			gmove(&r1, t);
   671  			regfree(&r1);
   672  			return;
   673  		}
   674  
   675  		f = &con;
   676  		ft = simsimtype(con.type);
   677  
   678  		// constants can't move directly to memory
   679  		if(ismem(t) && !is64(t->type)) goto hard;
   680  	}
   681  
   682  	// value -> value copy, only one memory operand.
   683  	// figure out the instruction to use.
   684  	// break out of switch for one-instruction gins.
   685  	// goto rdst for "destination must be register".
   686  	// goto hard for "convert to cvt type first".
   687  	// otherwise handle and return.
   688  
   689  	switch(CASE(ft, tt)) {
   690  	default:
   691  		goto fatal;
   692  
   693  	/*
   694  	 * integer copy and truncate
   695  	 */
   696  	case CASE(TINT8, TINT8):	// same size
   697  	case CASE(TUINT8, TINT8):
   698  	case CASE(TINT16, TINT8):	// truncate
   699  	case CASE(TUINT16, TINT8):
   700  	case CASE(TINT32, TINT8):
   701  	case CASE(TUINT32, TINT8):
   702  		a = AMOVB;
   703  		break;
   704  
   705  	case CASE(TINT8, TUINT8):
   706  	case CASE(TUINT8, TUINT8):
   707  	case CASE(TINT16, TUINT8):
   708  	case CASE(TUINT16, TUINT8):
   709  	case CASE(TINT32, TUINT8):
   710  	case CASE(TUINT32, TUINT8):
   711  		a = AMOVBU;
   712  		break;
   713  
   714  	case CASE(TINT64, TINT8):	// truncate low word
   715  	case CASE(TUINT64, TINT8):
   716  		a = AMOVB;
   717  		goto trunc64;
   718  
   719  	case CASE(TINT64, TUINT8):
   720  	case CASE(TUINT64, TUINT8):
   721  		a = AMOVBU;
   722  		goto trunc64;
   723  
   724  	case CASE(TINT16, TINT16):	// same size
   725  	case CASE(TUINT16, TINT16):
   726  	case CASE(TINT32, TINT16):	// truncate
   727  	case CASE(TUINT32, TINT16):
   728  		a = AMOVH;
   729  		break;
   730  
   731  	case CASE(TINT16, TUINT16):
   732  	case CASE(TUINT16, TUINT16):
   733  	case CASE(TINT32, TUINT16):
   734  	case CASE(TUINT32, TUINT16):
   735  		a = AMOVHU;
   736  		break;
   737  
   738  	case CASE(TINT64, TINT16):	// truncate low word
   739  	case CASE(TUINT64, TINT16):
   740  		a = AMOVH;
   741  		goto trunc64;
   742  
   743  	case CASE(TINT64, TUINT16):
   744  	case CASE(TUINT64, TUINT16):
   745  		a = AMOVHU;
   746  		goto trunc64;
   747  
   748  	case CASE(TINT32, TINT32):	// same size
   749  	case CASE(TINT32, TUINT32):
   750  	case CASE(TUINT32, TINT32):
   751  	case CASE(TUINT32, TUINT32):
   752  		a = AMOVW;
   753  		break;
   754  
   755  	case CASE(TINT64, TINT32):	// truncate
   756  	case CASE(TUINT64, TINT32):
   757  	case CASE(TINT64, TUINT32):
   758  	case CASE(TUINT64, TUINT32):
   759  		split64(f, &flo, &fhi);
   760  		regalloc(&r1, t->type, N);
   761  		gins(AMOVW, &flo, &r1);
   762  		gins(AMOVW, &r1, t);
   763  		regfree(&r1);
   764  		splitclean();
   765  		return;
   766  
   767  	case CASE(TINT64, TINT64):	// same size
   768  	case CASE(TINT64, TUINT64):
   769  	case CASE(TUINT64, TINT64):
   770  	case CASE(TUINT64, TUINT64):
   771  		split64(f, &flo, &fhi);
   772  		split64(t, &tlo, &thi);
   773  		regalloc(&r1, flo.type, N);
   774  		regalloc(&r2, fhi.type, N);
   775  		gins(AMOVW, &flo, &r1);
   776  		gins(AMOVW, &fhi, &r2);
   777  		gins(AMOVW, &r1, &tlo);
   778  		gins(AMOVW, &r2, &thi);
   779  		regfree(&r1);
   780  		regfree(&r2);
   781  		splitclean();
   782  		splitclean();
   783  		return;
   784  
   785  	/*
   786  	 * integer up-conversions
   787  	 */
   788  	case CASE(TINT8, TINT16):	// sign extend int8
   789  	case CASE(TINT8, TUINT16):
   790  	case CASE(TINT8, TINT32):
   791  	case CASE(TINT8, TUINT32):
   792  		a = AMOVB;
   793  		goto rdst;
   794  	case CASE(TINT8, TINT64):	// convert via int32
   795  	case CASE(TINT8, TUINT64):
   796  		cvt = types[TINT32];
   797  		goto hard;
   798  
   799  	case CASE(TUINT8, TINT16):	// zero extend uint8
   800  	case CASE(TUINT8, TUINT16):
   801  	case CASE(TUINT8, TINT32):
   802  	case CASE(TUINT8, TUINT32):
   803  		a = AMOVBU;
   804  		goto rdst;
   805  	case CASE(TUINT8, TINT64):	// convert via uint32
   806  	case CASE(TUINT8, TUINT64):
   807  		cvt = types[TUINT32];
   808  		goto hard;
   809  
   810  	case CASE(TINT16, TINT32):	// sign extend int16
   811  	case CASE(TINT16, TUINT32):
   812  		a = AMOVH;
   813  		goto rdst;
   814  	case CASE(TINT16, TINT64):	// convert via int32
   815  	case CASE(TINT16, TUINT64):
   816  		cvt = types[TINT32];
   817  		goto hard;
   818  
   819  	case CASE(TUINT16, TINT32):	// zero extend uint16
   820  	case CASE(TUINT16, TUINT32):
   821  		a = AMOVHU;
   822  		goto rdst;
   823  	case CASE(TUINT16, TINT64):	// convert via uint32
   824  	case CASE(TUINT16, TUINT64):
   825  		cvt = types[TUINT32];
   826  		goto hard;
   827  
   828  	case CASE(TINT32, TINT64):	// sign extend int32
   829  	case CASE(TINT32, TUINT64):
   830  		split64(t, &tlo, &thi);
   831  		regalloc(&r1, tlo.type, N);
   832  		regalloc(&r2, thi.type, N);
   833  		gmove(f, &r1);
   834  		p1 = gins(AMOVW, &r1, &r2);
   835  		p1->from.type = D_SHIFT;
   836  		p1->from.offset = 2 << 5 | 31 << 7 | r1.val.u.reg; // r1->31
   837  		p1->from.reg = NREG;
   838  //print("gmove: %P\n", p1);
   839  		gins(AMOVW, &r1, &tlo);
   840  		gins(AMOVW, &r2, &thi);
   841  		regfree(&r1);
   842  		regfree(&r2);
   843  		splitclean();
   844  		return;
   845  
   846  	case CASE(TUINT32, TINT64):	// zero extend uint32
   847  	case CASE(TUINT32, TUINT64):
   848  		split64(t, &tlo, &thi);
   849  		gmove(f, &tlo);
   850  		regalloc(&r1, thi.type, N);
   851  		gins(AMOVW, ncon(0), &r1);
   852  		gins(AMOVW, &r1, &thi);
   853  		regfree(&r1);
   854  		splitclean();
   855  		return;
   856  
   857  	/*
   858  	* float to integer
   859  	*/
   860  	case CASE(TFLOAT32, TINT8):
   861  	case CASE(TFLOAT32, TUINT8):
   862  	case CASE(TFLOAT32, TINT16):
   863  	case CASE(TFLOAT32, TUINT16):
   864  	case CASE(TFLOAT32, TINT32):
   865  	case CASE(TFLOAT32, TUINT32):
   866  //	case CASE(TFLOAT32, TUINT64):
   867  
   868  	case CASE(TFLOAT64, TINT8):
   869  	case CASE(TFLOAT64, TUINT8):
   870  	case CASE(TFLOAT64, TINT16):
   871  	case CASE(TFLOAT64, TUINT16):
   872  	case CASE(TFLOAT64, TINT32):
   873  	case CASE(TFLOAT64, TUINT32):
   874  //	case CASE(TFLOAT64, TUINT64):
   875  		fa = AMOVF;
   876  		a = AMOVFW;
   877  		if(ft == TFLOAT64) {
   878  			fa = AMOVD;
   879  			a = AMOVDW;
   880  		}
   881  		ta = AMOVW;
   882  		switch(tt) {
   883  		case TINT8:
   884  			ta = AMOVB;
   885  			break;
   886  		case TUINT8:
   887  			ta = AMOVBU;
   888  			break;
   889  		case TINT16:
   890  			ta = AMOVH;
   891  			break;
   892  		case TUINT16:
   893  			ta = AMOVHU;
   894  			break;
   895  		}
   896  
   897  		regalloc(&r1, types[ft], f);
   898  		regalloc(&r2, types[tt], t);
   899  		gins(fa, f, &r1);	// load to fpu
   900  		p1 = gins(a, &r1, &r1);	// convert to w
   901  		switch(tt) {
   902  		case TUINT8:
   903  		case TUINT16:
   904  		case TUINT32:
   905  			p1->scond |= C_UBIT;
   906  		}
   907  		gins(AMOVW, &r1, &r2);	// copy to cpu
   908  		gins(ta, &r2, t);	// store
   909  		regfree(&r1);
   910  		regfree(&r2);
   911  		return;
   912  
   913  	/*
   914  	 * integer to float
   915  	 */
   916  	case CASE(TINT8, TFLOAT32):
   917  	case CASE(TUINT8, TFLOAT32):
   918  	case CASE(TINT16, TFLOAT32):
   919  	case CASE(TUINT16, TFLOAT32):
   920  	case CASE(TINT32, TFLOAT32):
   921  	case CASE(TUINT32, TFLOAT32):
   922  	case CASE(TINT8, TFLOAT64):
   923  	case CASE(TUINT8, TFLOAT64):
   924  	case CASE(TINT16, TFLOAT64):
   925  	case CASE(TUINT16, TFLOAT64):
   926  	case CASE(TINT32, TFLOAT64):
   927  	case CASE(TUINT32, TFLOAT64):
   928  		fa = AMOVW;
   929  		switch(ft) {
   930  		case TINT8:
   931  			fa = AMOVB;
   932  			break;
   933  		case TUINT8:
   934  			fa = AMOVBU;
   935  			break;
   936  		case TINT16:
   937  			fa = AMOVH;
   938  			break;
   939  		case TUINT16:
   940  			fa = AMOVHU;
   941  			break;
   942  		}
   943  		a = AMOVWF;
   944  		ta = AMOVF;
   945  		if(tt == TFLOAT64) {
   946  			a = AMOVWD;
   947  			ta = AMOVD;
   948  		}
   949  		regalloc(&r1, types[ft], f);
   950  		regalloc(&r2, types[tt], t);
   951  		gins(fa, f, &r1);	// load to cpu
   952  		gins(AMOVW, &r1, &r2);	// copy to fpu
   953  		p1 = gins(a, &r2, &r2);	// convert
   954  		switch(ft) {
   955  		case TUINT8:
   956  		case TUINT16:
   957  		case TUINT32:
   958  			p1->scond |= C_UBIT;
   959  		}
   960  		gins(ta, &r2, t);	// store
   961  		regfree(&r1);
   962  		regfree(&r2);
   963  		return;
   964  
   965  	case CASE(TUINT64, TFLOAT32):
   966  	case CASE(TUINT64, TFLOAT64):
   967  		fatal("gmove UINT64, TFLOAT not implemented");
   968  		return;
   969  
   970  
   971  	/*
   972  	 * float to float
   973  	 */
   974  	case CASE(TFLOAT32, TFLOAT32):
   975  		a = AMOVF;
   976  		break;
   977  
   978  	case CASE(TFLOAT64, TFLOAT64):
   979  		a = AMOVD;
   980  		break;
   981  
   982  	case CASE(TFLOAT32, TFLOAT64):
   983  		regalloc(&r1, types[TFLOAT64], t);
   984  		gins(AMOVF, f, &r1);
   985  		gins(AMOVFD, &r1, &r1);
   986  		gins(AMOVD, &r1, t);
   987  		regfree(&r1);
   988  		return;
   989  
   990  	case CASE(TFLOAT64, TFLOAT32):
   991  		regalloc(&r1, types[TFLOAT64], t);
   992  		gins(AMOVD, f, &r1);
   993  		gins(AMOVDF, &r1, &r1);
   994  		gins(AMOVF, &r1, t);
   995  		regfree(&r1);
   996  		return;
   997  	}
   998  
   999  	gins(a, f, t);
  1000  	return;
  1001  
  1002  rdst:
  1003  	// TODO(kaib): we almost always require a register dest anyway, this can probably be
  1004  	// removed.
  1005  	// requires register destination
  1006  	regalloc(&r1, t->type, t);
  1007  	gins(a, f, &r1);
  1008  	gmove(&r1, t);
  1009  	regfree(&r1);
  1010  	return;
  1011  
  1012  hard:
  1013  	// requires register intermediate
  1014  	regalloc(&r1, cvt, t);
  1015  	gmove(f, &r1);
  1016  	gmove(&r1, t);
  1017  	regfree(&r1);
  1018  	return;
  1019  
  1020  trunc64:
  1021  	// truncate 64 bit integer
  1022  	split64(f, &flo, &fhi);
  1023  	regalloc(&r1, t->type, N);
  1024  	gins(a, &flo, &r1);
  1025  	gins(a, &r1, t);
  1026  	regfree(&r1);
  1027  	splitclean();
  1028  	return;
  1029  
  1030  fatal:
  1031  	// should not happen
  1032  	fatal("gmove %N -> %N", f, t);
  1033  }
  1034  
  1035  int
  1036  samaddr(Node *f, Node *t)
  1037  {
  1038  
  1039  	if(f->op != t->op)
  1040  		return 0;
  1041  
  1042  	switch(f->op) {
  1043  	case OREGISTER:
  1044  		if(f->val.u.reg != t->val.u.reg)
  1045  			break;
  1046  		return 1;
  1047  	}
  1048  	return 0;
  1049  }
  1050  
  1051  /*
  1052   * generate one instruction:
  1053   *	as f, t
  1054   */
  1055  Prog*
  1056  gins(int as, Node *f, Node *t)
  1057  {
  1058  //	Node nod;
  1059  //	int32 v;
  1060  	Prog *p;
  1061  	Addr af, at;
  1062  
  1063  	if(f != N && f->op == OINDEX) {
  1064  		fatal("gins OINDEX not implemented");
  1065  //		regalloc(&nod, &regnode, Z);
  1066  //		v = constnode.vconst;
  1067  //		cgen(f->right, &nod);
  1068  //		constnode.vconst = v;
  1069  //		idx.reg = nod.reg;
  1070  //		regfree(&nod);
  1071  	}
  1072  	if(t != N && t->op == OINDEX) {
  1073  		fatal("gins OINDEX not implemented");
  1074  //		regalloc(&nod, &regnode, Z);
  1075  //		v = constnode.vconst;
  1076  //		cgen(t->right, &nod);
  1077  //		constnode.vconst = v;
  1078  //		idx.reg = nod.reg;
  1079  //		regfree(&nod);
  1080  	}
  1081  
  1082  	memset(&af, 0, sizeof af);
  1083  	memset(&at, 0, sizeof at);
  1084  	if(f != N)
  1085  		naddr(f, &af, 1);
  1086  	if(t != N)
  1087  		naddr(t, &at, 1);
  1088  	p = prog(as);
  1089  	if(f != N)
  1090  		p->from = af;
  1091  	if(t != N)
  1092  		p->to = at;
  1093  	if(debug['g'])
  1094  		print("%P\n", p);
  1095  	return p;
  1096  }
  1097  
  1098  /*
  1099   * insert n into reg slot of p
  1100   */
  1101  void
  1102  raddr(Node *n, Prog *p)
  1103  {
  1104  	Addr a;
  1105  
  1106  	naddr(n, &a, 1);
  1107  	if(a.type != D_REG && a.type != D_FREG) {
  1108  		if(n)
  1109  			fatal("bad in raddr: %O", n->op);
  1110  		else
  1111  			fatal("bad in raddr: <null>");
  1112  		p->reg = NREG;
  1113  	} else
  1114  		p->reg = a.reg;
  1115  }
  1116  
  1117  /* generate a comparison
  1118  TODO(kaib): one of the args can actually be a small constant. relax the constraint and fix call sites.
  1119   */
  1120  Prog*
  1121  gcmp(int as, Node *lhs, Node *rhs)
  1122  {
  1123  	Prog *p;
  1124  
  1125  	if(lhs->op != OREGISTER)
  1126  		fatal("bad operands to gcmp: %O %O", lhs->op, rhs->op);
  1127  
  1128  	p = gins(as, rhs, N);
  1129  	raddr(lhs, p);
  1130  	return p;
  1131  }
  1132  
  1133  /* generate a constant shift
  1134   * arm encodes a shift by 32 as 0, thus asking for 0 shift is illegal.
  1135  */
  1136  Prog*
  1137  gshift(int as, Node *lhs, int32 stype, int32 sval, Node *rhs)
  1138  {
  1139  	Prog *p;
  1140  
  1141  	if(sval <= 0 || sval > 32)
  1142  		fatal("bad shift value: %d", sval);
  1143  
  1144  	sval = sval&0x1f;
  1145  
  1146  	p = gins(as, N, rhs);
  1147  	p->from.type = D_SHIFT;
  1148  	p->from.offset = stype | sval<<7 | lhs->val.u.reg;
  1149  	return p;
  1150  }
  1151  
  1152  /* generate a register shift
  1153  */
  1154  Prog *
  1155  gregshift(int as, Node *lhs, int32 stype, Node *reg, Node *rhs)
  1156  {
  1157  	Prog *p;
  1158  	p = gins(as, N, rhs);
  1159  	p->from.type = D_SHIFT;
  1160  	p->from.offset = stype | reg->val.u.reg << 8 | 1<<4 | lhs->val.u.reg;
  1161  	return p;
  1162  }
  1163  
  1164  // Generate an instruction referencing *n
  1165  // to force segv on nil pointer dereference.
  1166  void
  1167  checkref(Node *n, int force)
  1168  {
  1169  	Node m1, m2;
  1170  
  1171  	if(!force && isptr[n->type->etype] && n->type->type->width < unmappedzero)
  1172  		return;
  1173  
  1174  	regalloc(&m1, types[TUINTPTR], n);
  1175  	regalloc(&m2, types[TUINT8], n);
  1176  	cgen(n, &m1);
  1177  	m1.xoffset = 0;
  1178  	m1.op = OINDREG;
  1179  	m1.type = types[TUINT8];
  1180  	gins(AMOVBU, &m1, &m2);
  1181  	regfree(&m2);
  1182  	regfree(&m1);
  1183  }
  1184  
  1185  static void
  1186  checkoffset(Addr *a, int canemitcode)
  1187  {
  1188  	Prog *p;
  1189  	Node n1;
  1190  
  1191  	if(a->offset < unmappedzero)
  1192  		return;
  1193  	if(!canemitcode)
  1194  		fatal("checkoffset %#x, cannot emit code", a->offset);
  1195  
  1196  	// cannot rely on unmapped nil page at 0 to catch
  1197  	// reference with large offset.  instead, emit explicit
  1198  	// test of 0(reg).
  1199  	regalloc(&n1, types[TUINTPTR], N);
  1200  	p = gins(AMOVB, N, &n1);
  1201  	p->from = *a;
  1202  	p->from.offset = 0;
  1203  	regfree(&n1);
  1204  }
  1205  
  1206  /*
  1207   * generate code to compute n;
  1208   * make a refer to result.
  1209   */
  1210  void
  1211  naddr(Node *n, Addr *a, int canemitcode)
  1212  {
  1213  	a->type = D_NONE;
  1214  	a->name = D_NONE;
  1215  	a->reg = NREG;
  1216  	a->gotype = S;
  1217  	a->node = N;
  1218  	a->etype = 0;
  1219  	if(n == N)
  1220  		return;
  1221  
  1222  	if(n->type != T && n->type->etype != TIDEAL) {
  1223  		dowidth(n->type);
  1224  		a->width = n->type->width;
  1225  	}
  1226  
  1227  	switch(n->op) {
  1228  	default:
  1229  		fatal("naddr: bad %O %D", n->op, a);
  1230  		break;
  1231  
  1232  	case OREGISTER:
  1233  		if(n->val.u.reg <= REGALLOC_RMAX) {
  1234  			a->type = D_REG;
  1235  			a->reg = n->val.u.reg;
  1236  		} else {
  1237  			a->type = D_FREG;
  1238  			a->reg = n->val.u.reg - REGALLOC_F0;
  1239  		}
  1240  		a->sym = S;
  1241  		break;
  1242  
  1243  	case OINDEX:
  1244  	case OIND:
  1245  		fatal("naddr: OINDEX");
  1246  //		naddr(n->left, a);
  1247  //		if(a->type >= D_AX && a->type <= D_DI)
  1248  //			a->type += D_INDIR;
  1249  //		else
  1250  //		if(a->type == D_CONST)
  1251  //			a->type = D_NONE+D_INDIR;
  1252  //		else
  1253  //		if(a->type == D_ADDR) {
  1254  //			a->type = a->index;
  1255  //			a->index = D_NONE;
  1256  //		} else
  1257  //			goto bad;
  1258  //		if(n->op == OINDEX) {
  1259  //			a->index = idx.reg;
  1260  //			a->scale = n->scale;
  1261  //		}
  1262  //		break;
  1263  
  1264  	case OINDREG:
  1265  		a->type = D_OREG;
  1266  		a->reg = n->val.u.reg;
  1267  		a->sym = n->sym;
  1268  		a->offset = n->xoffset;
  1269  		checkoffset(a, canemitcode);
  1270  		break;
  1271  
  1272  	case OPARAM:
  1273  		// n->left is PHEAP ONAME for stack parameter.
  1274  		// compute address of actual parameter on stack.
  1275  		a->etype = simtype[n->left->type->etype];
  1276  		a->width = n->left->type->width;
  1277  		a->offset = n->xoffset;
  1278  		a->sym = n->left->sym;
  1279  		a->type = D_OREG;
  1280  		a->name = D_PARAM;
  1281  		a->node = n->left->orig;
  1282  		break;
  1283  	
  1284  	case OCLOSUREVAR:
  1285  		a->type = D_OREG;
  1286  		a->reg = 7;
  1287  		a->offset = n->xoffset;
  1288  		a->sym = S;
  1289  		break;		
  1290  
  1291  	case OCFUNC:
  1292  		naddr(n->left, a, canemitcode);
  1293  		a->sym = n->left->sym;
  1294  		break;
  1295  
  1296  	case ONAME:
  1297  		a->etype = 0;
  1298  		a->width = 0;
  1299  		a->reg = NREG;
  1300  		if(n->type != T) {
  1301  			a->etype = simtype[n->type->etype];
  1302  			a->width = n->type->width;
  1303  		}
  1304  		a->offset = n->xoffset;
  1305  		a->sym = n->sym;
  1306  		a->node = n->orig;
  1307  		//if(a->node >= (Node*)&n)
  1308  		//	fatal("stack node");
  1309  		if(a->sym == S)
  1310  			a->sym = lookup(".noname");
  1311  		if(n->method) {
  1312  			if(n->type != T)
  1313  			if(n->type->sym != S)
  1314  			if(n->type->sym->pkg != nil)
  1315  				a->sym = pkglookup(a->sym->name, n->type->sym->pkg);
  1316  		}
  1317  
  1318  		a->type = D_OREG;
  1319  		switch(n->class) {
  1320  		default:
  1321  			fatal("naddr: ONAME class %S %d\n", n->sym, n->class);
  1322  		case PEXTERN:
  1323  			a->name = D_EXTERN;
  1324  			break;
  1325  		case PAUTO:
  1326  			a->name = D_AUTO;
  1327  			break;
  1328  		case PPARAM:
  1329  		case PPARAMOUT:
  1330  			a->name = D_PARAM;
  1331  			break;
  1332  		case PFUNC:
  1333  			a->name = D_EXTERN;
  1334  			a->type = D_CONST;
  1335  			a->sym = funcsym(a->sym);
  1336  			break;
  1337  		}
  1338  		break;
  1339  
  1340  	case OLITERAL:
  1341  		switch(n->val.ctype) {
  1342  		default:
  1343  			fatal("naddr: const %lT", n->type);
  1344  			break;
  1345  		case CTFLT:
  1346  			a->type = D_FCONST;
  1347  			a->u.dval = mpgetflt(n->val.u.fval);
  1348  			break;
  1349  		case CTINT:
  1350  		case CTRUNE:
  1351  			a->sym = S;
  1352  			a->type = D_CONST;
  1353  			a->offset = mpgetfix(n->val.u.xval);
  1354  			break;
  1355  		case CTSTR:
  1356  			datagostring(n->val.u.sval, a);
  1357  			break;
  1358  		case CTBOOL:
  1359  			a->sym = S;
  1360  			a->type = D_CONST;
  1361  			a->offset = n->val.u.bval;
  1362  			break;
  1363  		case CTNIL:
  1364  			a->sym = S;
  1365  			a->type = D_CONST;
  1366  			a->offset = 0;
  1367  			break;
  1368  		}
  1369  		break;
  1370  
  1371  	case OITAB:
  1372  		// itable of interface value
  1373  		naddr(n->left, a, canemitcode);
  1374  		a->etype = TINT32;
  1375  		if(a->type == D_CONST && a->offset == 0)
  1376  			break;	// len(nil)
  1377  		if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero)
  1378  			checkoffset(a, canemitcode);
  1379  		break;
  1380  
  1381  	case OLEN:
  1382  		// len of string or slice
  1383  		naddr(n->left, a, canemitcode);
  1384  		a->etype = TINT32;
  1385  		if(a->type == D_CONST && a->offset == 0)
  1386  			break;	// len(nil)
  1387  		a->offset += Array_nel;
  1388  		if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero)
  1389  			checkoffset(a, canemitcode);
  1390  		break;
  1391  
  1392  	case OCAP:
  1393  		// cap of string or slice
  1394  		naddr(n->left, a, canemitcode);
  1395  		a->etype = TINT32;
  1396  		if(a->type == D_CONST && a->offset == 0)
  1397  			break;	// cap(nil)
  1398  		a->offset += Array_cap;
  1399  		if(a->offset >= unmappedzero && a->offset-Array_cap < unmappedzero)
  1400  			checkoffset(a, canemitcode);
  1401  		break;
  1402  
  1403  	case OADDR:
  1404  		naddr(n->left, a, canemitcode);
  1405  		a->etype = tptr;
  1406  		switch(a->type) {
  1407  		case D_OREG:
  1408  			a->type = D_CONST;
  1409  			break;
  1410  
  1411  		case D_REG:
  1412  		case D_CONST:
  1413  			break;
  1414  		
  1415  		default:
  1416  			fatal("naddr: OADDR %d\n", a->type);
  1417  		}
  1418  	}
  1419  	
  1420  	if(a->width < 0)
  1421  		fatal("naddr: bad width for %N -> %D", n, a);
  1422  }
  1423  
  1424  /*
  1425   * return Axxx for Oxxx on type t.
  1426   */
  1427  int
  1428  optoas(int op, Type *t)
  1429  {
  1430  	int a;
  1431  
  1432  	if(t == T)
  1433  		fatal("optoas: t is nil");
  1434  
  1435  	a = AGOK;
  1436  	switch(CASE(op, simtype[t->etype])) {
  1437  	default:
  1438  		fatal("optoas: no entry %O-%T etype %T simtype %T", op, t, types[t->etype], types[simtype[t->etype]]);
  1439  		break;
  1440  
  1441  /*	case CASE(OADDR, TPTR32):
  1442  		a = ALEAL;
  1443  		break;
  1444  
  1445  	case CASE(OADDR, TPTR64):
  1446  		a = ALEAQ;
  1447  		break;
  1448  */
  1449  	// TODO(kaib): make sure the conditional branches work on all edge cases
  1450  	case CASE(OEQ, TBOOL):
  1451  	case CASE(OEQ, TINT8):
  1452  	case CASE(OEQ, TUINT8):
  1453  	case CASE(OEQ, TINT16):
  1454  	case CASE(OEQ, TUINT16):
  1455  	case CASE(OEQ, TINT32):
  1456  	case CASE(OEQ, TUINT32):
  1457  	case CASE(OEQ, TINT64):
  1458  	case CASE(OEQ, TUINT64):
  1459  	case CASE(OEQ, TPTR32):
  1460  	case CASE(OEQ, TPTR64):
  1461  	case CASE(OEQ, TFLOAT32):
  1462  	case CASE(OEQ, TFLOAT64):
  1463  		a = ABEQ;
  1464  		break;
  1465  
  1466  	case CASE(ONE, TBOOL):
  1467  	case CASE(ONE, TINT8):
  1468  	case CASE(ONE, TUINT8):
  1469  	case CASE(ONE, TINT16):
  1470  	case CASE(ONE, TUINT16):
  1471  	case CASE(ONE, TINT32):
  1472  	case CASE(ONE, TUINT32):
  1473  	case CASE(ONE, TINT64):
  1474  	case CASE(ONE, TUINT64):
  1475  	case CASE(ONE, TPTR32):
  1476  	case CASE(ONE, TPTR64):
  1477  	case CASE(ONE, TFLOAT32):
  1478  	case CASE(ONE, TFLOAT64):
  1479  		a = ABNE;
  1480  		break;
  1481  
  1482  	case CASE(OLT, TINT8):
  1483  	case CASE(OLT, TINT16):
  1484  	case CASE(OLT, TINT32):
  1485  	case CASE(OLT, TINT64):
  1486  	case CASE(OLT, TFLOAT32):
  1487  	case CASE(OLT, TFLOAT64):
  1488  		a = ABLT;
  1489  		break;
  1490  
  1491  	case CASE(OLT, TUINT8):
  1492  	case CASE(OLT, TUINT16):
  1493  	case CASE(OLT, TUINT32):
  1494  	case CASE(OLT, TUINT64):
  1495  		a = ABLO;
  1496  		break;
  1497  
  1498  	case CASE(OLE, TINT8):
  1499  	case CASE(OLE, TINT16):
  1500  	case CASE(OLE, TINT32):
  1501  	case CASE(OLE, TINT64):
  1502  	case CASE(OLE, TFLOAT32):
  1503  	case CASE(OLE, TFLOAT64):
  1504  		a = ABLE;
  1505  		break;
  1506  
  1507  	case CASE(OLE, TUINT8):
  1508  	case CASE(OLE, TUINT16):
  1509  	case CASE(OLE, TUINT32):
  1510  	case CASE(OLE, TUINT64):
  1511  		a = ABLS;
  1512  		break;
  1513  
  1514  	case CASE(OGT, TINT8):
  1515  	case CASE(OGT, TINT16):
  1516  	case CASE(OGT, TINT32):
  1517  	case CASE(OGT, TINT64):
  1518  	case CASE(OGT, TFLOAT32):
  1519  	case CASE(OGT, TFLOAT64):
  1520  		a = ABGT;
  1521  		break;
  1522  
  1523  	case CASE(OGT, TUINT8):
  1524  	case CASE(OGT, TUINT16):
  1525  	case CASE(OGT, TUINT32):
  1526  	case CASE(OGT, TUINT64):
  1527  		a = ABHI;
  1528  		break;
  1529  
  1530  	case CASE(OGE, TINT8):
  1531  	case CASE(OGE, TINT16):
  1532  	case CASE(OGE, TINT32):
  1533  	case CASE(OGE, TINT64):
  1534  	case CASE(OGE, TFLOAT32):
  1535  	case CASE(OGE, TFLOAT64):
  1536  		a = ABGE;
  1537  		break;
  1538  
  1539  	case CASE(OGE, TUINT8):
  1540  	case CASE(OGE, TUINT16):
  1541  	case CASE(OGE, TUINT32):
  1542  	case CASE(OGE, TUINT64):
  1543  		a = ABHS;
  1544  		break;
  1545  
  1546  	case CASE(OCMP, TBOOL):
  1547  	case CASE(OCMP, TINT8):
  1548  	case CASE(OCMP, TUINT8):
  1549  	case CASE(OCMP, TINT16):
  1550  	case CASE(OCMP, TUINT16):
  1551  	case CASE(OCMP, TINT32):
  1552  	case CASE(OCMP, TUINT32):
  1553  	case CASE(OCMP, TPTR32):
  1554  		a = ACMP;
  1555  		break;
  1556  
  1557  	case CASE(OCMP, TFLOAT32):
  1558  		a = ACMPF;
  1559  		break;
  1560  
  1561  	case CASE(OCMP, TFLOAT64):
  1562  		a = ACMPD;
  1563  		break;
  1564  
  1565  	case CASE(OAS, TBOOL):
  1566  	case CASE(OAS, TINT8):
  1567  		a = AMOVB;
  1568  		break;
  1569  
  1570  	case CASE(OAS, TUINT8):
  1571  		a = AMOVBU;
  1572  		break;
  1573  
  1574  	case CASE(OAS, TINT16):
  1575  		a = AMOVH;
  1576  		break;
  1577  
  1578  	case CASE(OAS, TUINT16):
  1579  		a = AMOVHU;
  1580  		break;
  1581  
  1582  	case CASE(OAS, TINT32):
  1583  	case CASE(OAS, TUINT32):
  1584  	case CASE(OAS, TPTR32):
  1585  		a = AMOVW;
  1586  		break;
  1587  
  1588  	case CASE(OAS, TFLOAT32):
  1589  		a = AMOVF;
  1590  		break;
  1591  
  1592  	case CASE(OAS, TFLOAT64):
  1593  		a = AMOVD;
  1594  		break;
  1595  
  1596  	case CASE(OADD, TINT8):
  1597  	case CASE(OADD, TUINT8):
  1598  	case CASE(OADD, TINT16):
  1599  	case CASE(OADD, TUINT16):
  1600  	case CASE(OADD, TINT32):
  1601  	case CASE(OADD, TUINT32):
  1602  	case CASE(OADD, TPTR32):
  1603  		a = AADD;
  1604  		break;
  1605  
  1606  	case CASE(OADD, TFLOAT32):
  1607  		a = AADDF;
  1608  		break;
  1609  
  1610  	case CASE(OADD, TFLOAT64):
  1611  		a = AADDD;
  1612  		break;
  1613  
  1614  	case CASE(OSUB, TINT8):
  1615  	case CASE(OSUB, TUINT8):
  1616  	case CASE(OSUB, TINT16):
  1617  	case CASE(OSUB, TUINT16):
  1618  	case CASE(OSUB, TINT32):
  1619  	case CASE(OSUB, TUINT32):
  1620  	case CASE(OSUB, TPTR32):
  1621  		a = ASUB;
  1622  		break;
  1623  
  1624  	case CASE(OSUB, TFLOAT32):
  1625  		a = ASUBF;
  1626  		break;
  1627  
  1628  	case CASE(OSUB, TFLOAT64):
  1629  		a = ASUBD;
  1630  		break;
  1631  
  1632  	case CASE(OMINUS, TINT8):
  1633  	case CASE(OMINUS, TUINT8):
  1634  	case CASE(OMINUS, TINT16):
  1635  	case CASE(OMINUS, TUINT16):
  1636  	case CASE(OMINUS, TINT32):
  1637  	case CASE(OMINUS, TUINT32):
  1638  	case CASE(OMINUS, TPTR32):
  1639  		a = ARSB;
  1640  		break;
  1641  
  1642  	case CASE(OAND, TINT8):
  1643  	case CASE(OAND, TUINT8):
  1644  	case CASE(OAND, TINT16):
  1645  	case CASE(OAND, TUINT16):
  1646  	case CASE(OAND, TINT32):
  1647  	case CASE(OAND, TUINT32):
  1648  	case CASE(OAND, TPTR32):
  1649  		a = AAND;
  1650  		break;
  1651  
  1652  	case CASE(OOR, TINT8):
  1653  	case CASE(OOR, TUINT8):
  1654  	case CASE(OOR, TINT16):
  1655  	case CASE(OOR, TUINT16):
  1656  	case CASE(OOR, TINT32):
  1657  	case CASE(OOR, TUINT32):
  1658  	case CASE(OOR, TPTR32):
  1659  		a = AORR;
  1660  		break;
  1661  
  1662  	case CASE(OXOR, TINT8):
  1663  	case CASE(OXOR, TUINT8):
  1664  	case CASE(OXOR, TINT16):
  1665  	case CASE(OXOR, TUINT16):
  1666  	case CASE(OXOR, TINT32):
  1667  	case CASE(OXOR, TUINT32):
  1668  	case CASE(OXOR, TPTR32):
  1669  		a = AEOR;
  1670  		break;
  1671  
  1672  	case CASE(OLSH, TINT8):
  1673  	case CASE(OLSH, TUINT8):
  1674  	case CASE(OLSH, TINT16):
  1675  	case CASE(OLSH, TUINT16):
  1676  	case CASE(OLSH, TINT32):
  1677  	case CASE(OLSH, TUINT32):
  1678  	case CASE(OLSH, TPTR32):
  1679  		a = ASLL;
  1680  		break;
  1681  
  1682  	case CASE(ORSH, TUINT8):
  1683  	case CASE(ORSH, TUINT16):
  1684  	case CASE(ORSH, TUINT32):
  1685  	case CASE(ORSH, TPTR32):
  1686  		a = ASRL;
  1687  		break;
  1688  
  1689  	case CASE(ORSH, TINT8):
  1690  	case CASE(ORSH, TINT16):
  1691  	case CASE(ORSH, TINT32):
  1692  		a = ASRA;
  1693  		break;
  1694  
  1695  	case CASE(OMUL, TUINT8):
  1696  	case CASE(OMUL, TUINT16):
  1697  	case CASE(OMUL, TUINT32):
  1698  	case CASE(OMUL, TPTR32):
  1699  		a = AMULU;
  1700  		break;
  1701  
  1702  	case CASE(OMUL, TINT8):
  1703  	case CASE(OMUL, TINT16):
  1704  	case CASE(OMUL, TINT32):
  1705  		a = AMUL;
  1706  		break;
  1707  
  1708  	case CASE(OMUL, TFLOAT32):
  1709  		a = AMULF;
  1710  		break;
  1711  
  1712  	case CASE(OMUL, TFLOAT64):
  1713  		a = AMULD;
  1714  		break;
  1715  
  1716  	case CASE(ODIV, TUINT8):
  1717  	case CASE(ODIV, TUINT16):
  1718  	case CASE(ODIV, TUINT32):
  1719  	case CASE(ODIV, TPTR32):
  1720  		a = ADIVU;
  1721  		break;
  1722  
  1723  	case CASE(ODIV, TINT8):
  1724  	case CASE(ODIV, TINT16):
  1725  	case CASE(ODIV, TINT32):
  1726  		a = ADIV;
  1727  		break;
  1728  
  1729  	case CASE(OMOD, TUINT8):
  1730  	case CASE(OMOD, TUINT16):
  1731  	case CASE(OMOD, TUINT32):
  1732  	case CASE(OMOD, TPTR32):
  1733  		a = AMODU;
  1734  		break;
  1735  
  1736  	case CASE(OMOD, TINT8):
  1737  	case CASE(OMOD, TINT16):
  1738  	case CASE(OMOD, TINT32):
  1739  		a = AMOD;
  1740  		break;
  1741  
  1742  //	case CASE(OEXTEND, TINT16):
  1743  //		a = ACWD;
  1744  //		break;
  1745  
  1746  //	case CASE(OEXTEND, TINT32):
  1747  //		a = ACDQ;
  1748  //		break;
  1749  
  1750  //	case CASE(OEXTEND, TINT64):
  1751  //		a = ACQO;
  1752  //		break;
  1753  
  1754  	case CASE(ODIV, TFLOAT32):
  1755  		a = ADIVF;
  1756  		break;
  1757  
  1758  	case CASE(ODIV, TFLOAT64):
  1759  		a = ADIVD;
  1760  		break;
  1761  
  1762  	}
  1763  	return a;
  1764  }
  1765  
  1766  enum
  1767  {
  1768  	ODynam	= 1<<0,
  1769  	OPtrto	= 1<<1,
  1770  };
  1771  
  1772  static	Node	clean[20];
  1773  static	int	cleani = 0;
  1774  
  1775  void
  1776  sudoclean(void)
  1777  {
  1778  	if(clean[cleani-1].op != OEMPTY)
  1779  		regfree(&clean[cleani-1]);
  1780  	if(clean[cleani-2].op != OEMPTY)
  1781  		regfree(&clean[cleani-2]);
  1782  	cleani -= 2;
  1783  }
  1784  
  1785  int
  1786  dotaddable(Node *n, Node *n1)
  1787  {
  1788  	int o;
  1789  	int64 oary[10];
  1790  	Node *nn;
  1791  
  1792  	if(n->op != ODOT)
  1793  		return 0;
  1794  
  1795  	o = dotoffset(n, oary, &nn);
  1796  	if(nn != N && nn->addable && o == 1 && oary[0] >= 0) {
  1797  		*n1 = *nn;
  1798  		n1->type = n->type;
  1799  		n1->xoffset += oary[0];
  1800  		return 1;
  1801  	}
  1802  	return 0;
  1803  }
  1804  
  1805  /*
  1806   * generate code to compute address of n,
  1807   * a reference to a (perhaps nested) field inside
  1808   * an array or struct.
  1809   * return 0 on failure, 1 on success.
  1810   * on success, leaves usable address in a.
  1811   *
  1812   * caller is responsible for calling sudoclean
  1813   * after successful sudoaddable,
  1814   * to release the register used for a.
  1815   */
  1816  int
  1817  sudoaddable(int as, Node *n, Addr *a, int *w)
  1818  {
  1819  	int o, i;
  1820  	int64 oary[10];
  1821  	int64 v;
  1822  	Node n1, n2, n3, n4, *nn, *l, *r;
  1823  	Node *reg, *reg1;
  1824  	Prog *p1, *p2;
  1825  	Type *t;
  1826  
  1827  	if(n->type == T)
  1828  		return 0;
  1829  
  1830  	switch(n->op) {
  1831  	case OLITERAL:
  1832  		if(!isconst(n, CTINT))
  1833  			break;
  1834  		v = mpgetfix(n->val.u.xval);
  1835  		if(v >= 32000 || v <= -32000)
  1836  			break;
  1837  		goto lit;
  1838  
  1839  	case ODOT:
  1840  	case ODOTPTR:
  1841  		cleani += 2;
  1842  		reg = &clean[cleani-1];
  1843  		reg1 = &clean[cleani-2];
  1844  		reg->op = OEMPTY;
  1845  		reg1->op = OEMPTY;
  1846  		goto odot;
  1847  
  1848  	case OINDEX:
  1849  		return 0;
  1850  		// disabled: OINDEX case is now covered by agenr
  1851  		// for a more suitable register allocation pattern.
  1852  		if(n->left->type->etype == TSTRING)
  1853  			return 0;
  1854  		cleani += 2;
  1855  		reg = &clean[cleani-1];
  1856  		reg1 = &clean[cleani-2];
  1857  		reg->op = OEMPTY;
  1858  		reg1->op = OEMPTY;
  1859  		goto oindex;
  1860  	}
  1861  	return 0;
  1862  
  1863  lit:
  1864  	switch(as) {
  1865  	default:
  1866  		return 0;
  1867  	case AADD: case ASUB: case AAND: case AORR: case AEOR:
  1868  	case AMOVB: case AMOVBU: case AMOVH: case AMOVHU:
  1869  	case AMOVW:
  1870  		break;
  1871  	}
  1872  
  1873  	cleani += 2;
  1874  	reg = &clean[cleani-1];
  1875  	reg1 = &clean[cleani-2];
  1876  	reg->op = OEMPTY;
  1877  	reg1->op = OEMPTY;
  1878  	naddr(n, a, 1);
  1879  	goto yes;
  1880  
  1881  odot:
  1882  	o = dotoffset(n, oary, &nn);
  1883  	if(nn == N)
  1884  		goto no;
  1885  
  1886  	if(nn->addable && o == 1 && oary[0] >= 0) {
  1887  		// directly addressable set of DOTs
  1888  		n1 = *nn;
  1889  		n1.type = n->type;
  1890  		n1.xoffset += oary[0];
  1891  		naddr(&n1, a, 1);
  1892  		goto yes;
  1893  	}
  1894  
  1895  	regalloc(reg, types[tptr], N);
  1896  	n1 = *reg;
  1897  	n1.op = OINDREG;
  1898  	if(oary[0] >= 0) {
  1899  		agen(nn, reg);
  1900  		n1.xoffset = oary[0];
  1901  	} else {
  1902  		cgen(nn, reg);
  1903  		n1.xoffset = -(oary[0]+1);
  1904  	}
  1905  
  1906  	for(i=1; i<o; i++) {
  1907  		if(oary[i] >= 0)
  1908  			fatal("cant happen");
  1909  		gins(AMOVW, &n1, reg);
  1910  		n1.xoffset = -(oary[i]+1);
  1911  	}
  1912  
  1913  	a->type = D_NONE;
  1914  	a->name = D_NONE;
  1915  	n1.type = n->type;
  1916  	naddr(&n1, a, 1);
  1917  	goto yes;
  1918  
  1919  oindex:
  1920  	l = n->left;
  1921  	r = n->right;
  1922  	if(l->ullman >= UINF && r->ullman >= UINF)
  1923  		goto no;
  1924  
  1925  	// set o to type of array
  1926  	o = 0;
  1927  	if(isptr[l->type->etype]) {
  1928  		o += OPtrto;
  1929  		if(l->type->type->etype != TARRAY)
  1930  			fatal("not ptr ary");
  1931  		if(l->type->type->bound < 0)
  1932  			o += ODynam;
  1933  	} else {
  1934  		if(l->type->etype != TARRAY)
  1935  			fatal("not ary");
  1936  		if(l->type->bound < 0)
  1937  			o += ODynam;
  1938  	}
  1939  
  1940  	*w = n->type->width;
  1941  	if(isconst(r, CTINT))
  1942  		goto oindex_const;
  1943  
  1944  	switch(*w) {
  1945  	default:
  1946  		goto no;
  1947  	case 1:
  1948  	case 2:
  1949  	case 4:
  1950  	case 8:
  1951  		break;
  1952  	}
  1953  
  1954  	// load the array (reg)
  1955  	if(l->ullman > r->ullman) {
  1956  		regalloc(reg, types[tptr], N);
  1957  		if(o & OPtrto)
  1958  			cgen(l, reg);
  1959  		else
  1960  			agen(l, reg);
  1961  	}
  1962  
  1963  	// load the index (reg1)
  1964  	t = types[TUINT32];
  1965  	if(issigned[r->type->etype])
  1966  		t = types[TINT32];
  1967  	regalloc(reg1, t, N);
  1968  	regalloc(&n3, types[TINT32], reg1);
  1969  	p2 = cgenindex(r, &n3, debug['B'] || n->bounded);
  1970  	gmove(&n3, reg1);
  1971  	regfree(&n3);
  1972  
  1973  	// load the array (reg)
  1974  	if(l->ullman <= r->ullman) {
  1975  		regalloc(reg, types[tptr], N);
  1976  		if(o & OPtrto)
  1977  			cgen(l, reg);
  1978  		else
  1979  			agen(l, reg);
  1980  	}
  1981  
  1982  	// check bounds
  1983  	if(!debug['B']) {
  1984  		if(o & ODynam) {
  1985  			n2 = *reg;
  1986  			n2.op = OINDREG;
  1987  			n2.type = types[tptr];
  1988  			n2.xoffset = Array_nel;
  1989  		} else {
  1990  			if(l->type->width >= unmappedzero && l->op == OIND) {
  1991  				// cannot rely on page protections to
  1992  				// catch array ptr == 0, so dereference.
  1993  				n2 = *reg;
  1994  				n2.op = OINDREG;
  1995  				n2.type = types[TUINTPTR];
  1996  				n2.xoffset = 0;
  1997  				regalloc(&n3, n2.type, N);
  1998  				gins(AMOVW, &n2, &n3);
  1999  				regfree(&n3);
  2000  			}
  2001  			nodconst(&n2, types[TUINT32], l->type->bound);
  2002  			if(o & OPtrto)
  2003  				nodconst(&n2, types[TUINT32], l->type->type->bound);
  2004  		}
  2005  		regalloc(&n3, n2.type, N);
  2006  		cgen(&n2, &n3);
  2007  		gcmp(optoas(OCMP, types[TUINT32]), reg1, &n3);
  2008  		regfree(&n3);
  2009  		p1 = gbranch(optoas(OLT, types[TUINT32]), T, +1);
  2010  		if(p2)
  2011  			patch(p2, pc);
  2012  		ginscall(panicindex, 0);
  2013  		patch(p1, pc);
  2014  	}
  2015  
  2016  	if(o & ODynam) {
  2017  		n2 = *reg;
  2018  		n2.op = OINDREG;
  2019  		n2.type = types[tptr];
  2020  		n2.xoffset = Array_array;
  2021  		gmove(&n2, reg);
  2022  	}
  2023  
  2024  	switch(*w) {
  2025  	case 1:
  2026  		gins(AADD, reg1, reg);
  2027  		break;
  2028  	case 2:
  2029  		gshift(AADD, reg1, SHIFT_LL, 1, reg);
  2030  		break;
  2031  	case 4:
  2032  		gshift(AADD, reg1, SHIFT_LL, 2, reg);
  2033  		break;
  2034  	case 8:
  2035  		gshift(AADD, reg1, SHIFT_LL, 3, reg);
  2036  		break;
  2037  	}
  2038  
  2039  	naddr(reg1, a, 1);
  2040  	a->type = D_OREG;
  2041  	a->reg = reg->val.u.reg;
  2042  	a->offset = 0;
  2043  	goto yes;
  2044  
  2045  oindex_const:
  2046  	// index is constant
  2047  	// can check statically and
  2048  	// can multiply by width statically
  2049  
  2050  	regalloc(reg, types[tptr], N);
  2051  	if(o & OPtrto)
  2052  		cgen(l, reg);
  2053  	else
  2054  		agen(l, reg);
  2055  
  2056  	v = mpgetfix(r->val.u.xval);
  2057  	if(o & ODynam) {
  2058  
  2059  		if(!debug['B'] && !n->bounded) {
  2060  			n1 = *reg;
  2061  			n1.op = OINDREG;
  2062  			n1.type = types[tptr];
  2063  			n1.xoffset = Array_nel;
  2064  			nodconst(&n2, types[TUINT32], v);
  2065  			regalloc(&n3, types[TUINT32], N);
  2066  			cgen(&n2, &n3);
  2067  			regalloc(&n4, n1.type, N);
  2068  			cgen(&n1, &n4);
  2069  			gcmp(optoas(OCMP, types[TUINT32]), &n4, &n3);
  2070  			regfree(&n4);
  2071  			regfree(&n3);
  2072  			p1 = gbranch(optoas(OGT, types[TUINT32]), T, +1);
  2073  			ginscall(panicindex, 0);
  2074  			patch(p1, pc);
  2075  		}
  2076  
  2077  		n1 = *reg;
  2078  		n1.op = OINDREG;
  2079  		n1.type = types[tptr];
  2080  		n1.xoffset = Array_array;
  2081  		gmove(&n1, reg);
  2082  	}
  2083  
  2084  	n2 = *reg;
  2085  	n2.op = OINDREG;
  2086  	n2.xoffset = v * (*w);
  2087  	a->type = D_NONE;
  2088  	a->name = D_NONE;
  2089  	naddr(&n2, a, 1);
  2090  	goto yes;
  2091  
  2092  yes:
  2093  	return 1;
  2094  
  2095  no:
  2096  	sudoclean();
  2097  	return 0;
  2098  }