github.com/hbdrawn/golang@v0.0.0-20141214014649-6b835209aba2/src/cmd/9g/gsubr.c (about)

     1  // Derived from Inferno utils/6c/txt.c
     2  // http://code.google.com/p/inferno-os/source/browse/utils/6c/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  #include "../../runtime/funcdata.h"
    35  
    36  // TODO(rsc): Can make this bigger if we move
    37  // the text segment up higher in 6l for all GOOS.
    38  // At the same time, can raise StackBig in ../../runtime/stack.h.
    39  vlong unmappedzero = 4096;
    40  
    41  void
    42  clearp(Prog *p)
    43  {
    44  	*p = zprog;
    45  	p->as = AEND;
    46  	p->pc = pcloc;
    47  	pcloc++;
    48  }
    49  
    50  static int ddumped;
    51  static Prog *dfirst;
    52  static Prog *dpc;
    53  
    54  /*
    55   * generate and return proc with p->as = as,
    56   * linked into program. pc is next instruction.
    57   */
    58  Prog*
    59  prog(int as)
    60  {
    61  	Prog *p;
    62  
    63  	if(as == ADATA || as == AGLOBL) {
    64  		if(ddumped)
    65  			fatal("already dumped data");
    66  		if(dpc == nil) {
    67  			dpc = mal(sizeof(*dpc));
    68  			dfirst = dpc;
    69  		}
    70  		p = dpc;
    71  		dpc = mal(sizeof(*dpc));
    72  		p->link = dpc;
    73  		p->reg = 0; // used for flags
    74  	} else {
    75  		p = pc;
    76  		pc = mal(sizeof(*pc));
    77  		clearp(pc);
    78  		p->link = pc;
    79  	}
    80  
    81  	if(lineno == 0) {
    82  		if(debug['K'])
    83  			warn("prog: line 0");
    84  	}
    85  
    86  	p->as = as;
    87  	p->lineno = lineno;
    88  	return p;
    89  }
    90  
    91  void
    92  dumpdata(void)
    93  {
    94  	ddumped = 1;
    95  	if(dfirst == nil)
    96  		return;
    97  	newplist();
    98  	*pc = *dfirst;
    99  	pc = dpc;
   100  	clearp(pc);
   101  }
   102  
   103  /*
   104   * generate a branch.
   105   * t is ignored.
   106   * likely values are for branch prediction:
   107   *	-1 unlikely
   108   *	0 no opinion
   109   *	+1 likely
   110   */
   111  Prog*
   112  gbranch(int as, Type *t, int likely)
   113  {
   114  	Prog *p;
   115  	
   116  	USED(t);
   117  
   118  	p = prog(as);
   119  	p->to.type = D_BRANCH;
   120  	p->to.u.branch = P;
   121  	// TODO(minux): Enable this code.
   122  	// Note: liblink used Bcc CR0, label form, so we need another way
   123  	// to set likely/unlikely flag. Also note the y bit is not exactly
   124  	// likely/unlikely bit.
   125  	if(0 && as != ABR && likely != 0) {
   126  		p->from.type = D_CONST;
   127  		p->from.offset = likely > 0;
   128  	}
   129  	return p;
   130  }
   131  
   132  /*
   133   * patch previous branch to jump to to.
   134   */
   135  void
   136  patch(Prog *p, Prog *to)
   137  {
   138  	if(p->to.type != D_BRANCH)
   139  		fatal("patch: not a branch");
   140  	p->to.u.branch = to;
   141  	p->to.offset = to->pc;
   142  }
   143  
   144  Prog*
   145  unpatch(Prog *p)
   146  {
   147  	Prog *q;
   148  
   149  	if(p->to.type != D_BRANCH)
   150  		fatal("unpatch: not a branch");
   151  	q = p->to.u.branch;
   152  	p->to.u.branch = P;
   153  	p->to.offset = 0;
   154  	return q;
   155  }
   156  
   157  /*
   158   * start a new Prog list.
   159   */
   160  Plist*
   161  newplist(void)
   162  {
   163  	Plist *pl;
   164  
   165  	pl = linknewplist(ctxt);
   166  
   167  	pc = mal(sizeof(*pc));
   168  	clearp(pc);
   169  	pl->firstpc = pc;
   170  
   171  	return pl;
   172  }
   173  
   174  void
   175  gused(Node *n)
   176  {
   177  	gins(ANOP, n, N);	// used
   178  }
   179  
   180  Prog*
   181  gjmp(Prog *to)
   182  {
   183  	Prog *p;
   184  
   185  	p = gbranch(ABR, T, 0);
   186  	if(to != P)
   187  		patch(p, to);
   188  	return p;
   189  }
   190  
   191  void
   192  ggloblnod(Node *nam)
   193  {
   194  	Prog *p;
   195  
   196  	p = gins(AGLOBL, nam, N);
   197  	p->lineno = nam->lineno;
   198  	p->from.sym->gotype = linksym(ngotype(nam));
   199  	p->to.sym = nil;
   200  	p->to.type = D_CONST;
   201  	p->to.offset = nam->type->width;
   202  	if(nam->readonly)
   203  		p->reg = RODATA;
   204  	if(nam->type != T && !haspointers(nam->type))
   205  		p->reg |= NOPTR;
   206  }
   207  
   208  void
   209  gtrack(Sym *s)
   210  {
   211  	Prog *p;
   212  	
   213  	p = gins(AUSEFIELD, N, N);
   214  	p->from.type = D_OREG;
   215  	p->from.name = D_EXTERN;
   216  	p->from.sym = linksym(s);
   217  }
   218  
   219  void
   220  ggloblsym(Sym *s, int32 width, int8 flags)
   221  {
   222  	Prog *p;
   223  
   224  	p = gins(AGLOBL, N, N);
   225  	p->from.type = D_OREG;
   226  	p->from.name = D_EXTERN;
   227  	p->from.sym = linksym(s);
   228  	p->to.type = D_CONST;
   229  	p->to.name = D_NONE;
   230  	p->to.offset = width;
   231  	p->reg = flags;
   232  }
   233  
   234  int
   235  isfat(Type *t)
   236  {
   237  	if(t != T)
   238  	switch(t->etype) {
   239  	case TSTRUCT:
   240  	case TARRAY:
   241  	case TSTRING:
   242  	case TINTER:	// maybe remove later
   243  		return 1;
   244  	}
   245  	return 0;
   246  }
   247  
   248  /*
   249   * naddr of func generates code for address of func.
   250   * if using opcode that can take address implicitly,
   251   * call afunclit to fix up the argument.
   252   */
   253  void
   254  afunclit(Addr *a, Node *n)
   255  {
   256  	if(a->type == D_CONST && a->name == D_EXTERN) {
   257  		a->type = D_OREG;
   258  		a->sym = linksym(n->sym);
   259  	}
   260  }
   261  
   262  static	int	resvd[] =
   263  {
   264  	REGZERO,
   265  	REGSP,	// reserved for SP, XXX: not reserved in 9c.
   266  	30,	// for g
   267  	REGTMP,	// REGTMP
   268  	FREGCVI+NREG,
   269  	FREGZERO+NREG,
   270  	FREGHALF+NREG,
   271  	FREGONE+NREG,
   272  	FREGTWO+NREG,
   273  };
   274  
   275  void
   276  ginit(void)
   277  {
   278  	int i;
   279  
   280  	for(i=0; i<nelem(reg); i++)
   281  		reg[i] = 1;
   282  	for(i=0; i<NREG; i++)
   283  		reg[i] = 0;
   284  	for(i=NREG; i<NREG+NREG; i++)
   285  		reg[i] = 0;
   286  
   287  	for(i=0; i<nelem(resvd); i++)
   288  		reg[resvd[i]]++;
   289  }
   290  
   291  static	uintptr	regpc[nelem(reg)];
   292  
   293  void
   294  gclean(void)
   295  {
   296  	int i;
   297  
   298  	for(i=0; i<nelem(resvd); i++)
   299  		reg[resvd[i]]--;
   300  
   301  	for(i=0; i<nelem(reg); i++)
   302  		if(reg[i])
   303  			yyerror("reg %R left allocated, %p\n", i, regpc[i]);
   304  }
   305  
   306  int32
   307  anyregalloc(void)
   308  {
   309  	int i, j;
   310  
   311  	for(i=0; i<nelem(reg); i++) {
   312  		if(reg[i] == 0)
   313  			goto ok;
   314  		for(j=0; j<nelem(resvd); j++)
   315  			if(resvd[j] == i)
   316  				goto ok;
   317  		return 1;
   318  	ok:;
   319  	}
   320  	return 0;
   321  }
   322  
   323  /*
   324   * allocate register of type t, leave in n.
   325   * if o != N, o is desired fixed register.
   326   * caller must regfree(n).
   327   */
   328  void
   329  regalloc(Node *n, Type *t, Node *o)
   330  {
   331  	int i, et;
   332  	int fixfree, fltfree;
   333  
   334  	if(t == T)
   335  		fatal("regalloc: t nil");
   336  	et = simtype[t->etype];
   337  
   338  	if(debug['r']) {
   339  		fixfree = 0;
   340  		fltfree = 0;
   341  		for(i = D_R0; i < D_F0+NREG; i++)
   342  			if(reg[i] == 0) {
   343  				if(i < D_F0)
   344  					fixfree++;
   345  				else
   346  					fltfree++;
   347  			}
   348  		print("regalloc fix %d flt %d free\n", fixfree, fltfree);
   349  	}
   350  
   351  	switch(et) {
   352  	case TINT8:
   353  	case TUINT8:
   354  	case TINT16:
   355  	case TUINT16:
   356  	case TINT32:
   357  	case TUINT32:
   358  	case TINT64:
   359  	case TUINT64:
   360  	case TPTR32:
   361  	case TPTR64:
   362  	case TBOOL:
   363  		if(o != N && o->op == OREGISTER) {
   364  			i = o->val.u.reg;
   365  			if(i >= D_R0+REGMIN && i <= D_R0+REGMAX)
   366  				goto out;
   367  		}
   368  		for(i=D_R0+REGMIN; i<=D_R0+REGMAX; i++)
   369  			if(reg[i] == 0) {
   370  				regpc[i] = (uintptr)getcallerpc(&n);
   371  				goto out;
   372  			}
   373  		flusherrors();
   374  		for(i=D_R0; i<D_R0+NREG; i++)
   375  			print("R%d %p\n", i, regpc[i]);
   376  		fatal("out of fixed registers");
   377  
   378  	case TFLOAT32:
   379  	case TFLOAT64:
   380  		if(o != N && o->op == OREGISTER) {
   381  			i = o->val.u.reg;
   382  			if(i >= D_F0+FREGMIN && i <= D_F0+FREGMAX)
   383  				goto out;
   384  		}
   385  		for(i=D_F0+FREGMIN; i<=D_F0+FREGMAX; i++)
   386  			if(reg[i] == 0) {
   387  				regpc[i] = (uintptr)getcallerpc(&n);
   388  				goto out;
   389  			}
   390  		flusherrors();
   391  		for(i=D_F0; i<D_F0+NREG; i++)
   392  			print("F%d %p\n", i, regpc[i]);
   393  		fatal("out of floating registers");
   394  
   395  	case TCOMPLEX64:
   396  	case TCOMPLEX128:
   397  		tempname(n, t);
   398  		return;
   399  	}
   400  	fatal("regalloc: unknown type %T", t);
   401  	return;
   402  
   403  out:
   404  	reg[i]++;
   405  	nodreg(n, t, i);
   406  }
   407  
   408  void
   409  regfree(Node *n)
   410  {
   411  	int i;
   412  
   413  	if(n->op == ONAME)
   414  		return;
   415  	if(n->op != OREGISTER && n->op != OINDREG)
   416  		fatal("regfree: not a register");
   417  	i = n->val.u.reg;
   418  	if(i == D_R0 + REGSP)
   419  		return;
   420  	if(i < 0 || i >= nelem(reg))
   421  		fatal("regfree: reg out of range");
   422  	if(reg[i] <= 0)
   423  		fatal("regfree: reg not allocated");
   424  	reg[i]--;
   425  	if(reg[i] == 0)
   426  		regpc[i] = 0;
   427  }
   428  
   429  /*
   430   * initialize n to be register r of type t.
   431   */
   432  void
   433  nodreg(Node *n, Type *t, int r)
   434  {
   435  	if(t == T)
   436  		fatal("nodreg: t nil");
   437  
   438  	memset(n, 0, sizeof(*n));
   439  	n->op = OREGISTER;
   440  	n->addable = 1;
   441  	ullmancalc(n);
   442  	n->val.u.reg = r;
   443  	n->type = t;
   444  }
   445  
   446  /*
   447   * initialize n to be indirect of register r; n is type t.
   448   */
   449  void
   450  nodindreg(Node *n, Type *t, int r)
   451  {
   452  	nodreg(n, t, r);
   453  	n->op = OINDREG;
   454  }
   455  
   456  Node*
   457  nodarg(Type *t, int fp)
   458  {
   459  	Node *n;
   460  	NodeList *l;
   461  	Type *first;
   462  	Iter savet;
   463  
   464  	// entire argument struct, not just one arg
   465  	if(t->etype == TSTRUCT && t->funarg) {
   466  		n = nod(ONAME, N, N);
   467  		n->sym = lookup(".args");
   468  		n->type = t;
   469  		first = structfirst(&savet, &t);
   470  		if(first == nil)
   471  			fatal("nodarg: bad struct");
   472  		if(first->width == BADWIDTH)
   473  			fatal("nodarg: offset not computed for %T", t);
   474  		n->xoffset = first->width;
   475  		n->addable = 1;
   476  		goto fp;
   477  	}
   478  
   479  	if(t->etype != TFIELD)
   480  		fatal("nodarg: not field %T", t);
   481  	
   482  	if(fp == 1) {
   483  		for(l=curfn->dcl; l; l=l->next) {
   484  			n = l->n;
   485  			if((n->class == PPARAM || n->class == PPARAMOUT) && !isblanksym(t->sym) && n->sym == t->sym)
   486  				return n;
   487  		}
   488  	}
   489  
   490  	n = nod(ONAME, N, N);
   491  	n->type = t->type;
   492  	n->sym = t->sym;
   493  	
   494  	if(t->width == BADWIDTH)
   495  		fatal("nodarg: offset not computed for %T", t);
   496  	n->xoffset = t->width;
   497  	n->addable = 1;
   498  	n->orig = t->nname;
   499  
   500  fp:
   501  	// Rewrite argument named _ to __,
   502  	// or else the assignment to _ will be
   503  	// discarded during code generation.
   504  	if(isblank(n))
   505  		n->sym = lookup("__");
   506  
   507  	switch(fp) {
   508  	default:
   509  		fatal("nodarg %T %d", t, fp);
   510  
   511  	case 0:		// output arg for calling another function
   512  		n->op = OINDREG;
   513  		n->val.u.reg = D_R0+REGSP;
   514  		n->xoffset += 8;
   515  		break;
   516  
   517  	case 1:		// input arg to current function
   518  		n->class = PPARAM;
   519  		break;
   520  
   521  	case 2:		// offset output arg
   522  fatal("shouldn't be used");
   523  		n->op = OINDREG;
   524  		n->val.u.reg = D_R0 + REGSP;
   525  		n->xoffset += types[tptr]->width;
   526  		break;
   527  	}
   528  	n->typecheck = 1;
   529  	return n;
   530  }
   531  
   532  /*
   533   * generate
   534   *	as $c, n
   535   */
   536  void
   537  ginscon(int as, vlong c, Node *n2)
   538  {
   539  	Node n1, ntmp;
   540  
   541  	nodconst(&n1, types[TINT64], c);
   542  
   543  	if(as != AMOVD && (c < -BIG || c > BIG)) {
   544  		// cannot have more than 16-bit of immediate in ADD, etc.
   545  		// instead, MOV into register first.
   546  		regalloc(&ntmp, types[TINT64], N);
   547  		gins(AMOVD, &n1, &ntmp);
   548  		gins(as, &ntmp, n2);
   549  		regfree(&ntmp);
   550  		return;
   551  	}
   552  	gins(as, &n1, n2);
   553  }
   554  
   555  /*
   556   * generate
   557   *	as n, $c (CMP/CMPU)
   558   */
   559  void
   560  ginscon2(int as, Node *n2, vlong c)
   561  {
   562  	Node n1, ntmp;
   563  
   564  	nodconst(&n1, types[TINT64], c);
   565  
   566  	switch(as) {
   567  	default:
   568  		fatal("ginscon2");
   569  	case ACMP:
   570  		if(-BIG <= c && c <= BIG) {
   571  			gins(as, n2, &n1);
   572  			return;
   573  		}
   574  		break;
   575  	case ACMPU:
   576  		if(0 <= c && c <= 2*BIG) {
   577  			gins(as, n2, &n1);
   578  			return;
   579  		}
   580  		break;
   581  	}
   582  	// MOV n1 into register first
   583  	regalloc(&ntmp, types[TINT64], N);
   584  	gins(AMOVD, &n1, &ntmp);
   585  	gins(as, n2, &ntmp);
   586  	regfree(&ntmp);
   587  }
   588  
   589  #define	CASE(a,b)	(((a)<<16)|((b)<<0))
   590  /*c2go int CASE(int, int); */
   591  
   592  /*
   593   * Is this node a memory operand?
   594   */
   595  int
   596  ismem(Node *n)
   597  {
   598  	switch(n->op) {
   599  	case OITAB:
   600  	case OSPTR:
   601  	case OLEN:
   602  	case OCAP:
   603  	case OINDREG:
   604  	case ONAME:
   605  	case OPARAM:
   606  	case OCLOSUREVAR:
   607  	case OADDR:
   608  		return 1;
   609  	}
   610  	return 0;
   611  }
   612  
   613  /*
   614   * set up nodes representing 2^63
   615   */
   616  Node bigi;
   617  Node bigf;
   618  
   619  void
   620  bignodes(void)
   621  {
   622  	static int did;
   623  
   624  	if(did)
   625  		return;
   626  	did = 1;
   627  
   628  	nodconst(&bigi, types[TUINT64], 1);
   629  	mpshiftfix(bigi.val.u.xval, 63);
   630  
   631  	bigf = bigi;
   632  	bigf.type = types[TFLOAT64];
   633  	bigf.val.ctype = CTFLT;
   634  	bigf.val.u.fval = mal(sizeof *bigf.val.u.fval);
   635  	mpmovefixflt(bigf.val.u.fval, bigi.val.u.xval);
   636  }
   637  
   638  /*
   639   * generate move:
   640   *	t = f
   641   * hard part is conversions.
   642   */
   643  void
   644  gmove(Node *f, Node *t)
   645  {
   646  	int a, ft, tt;
   647  	Type *cvt;
   648  	Node r1, r2, r3, con;
   649  	Prog *p1, *p2;
   650  
   651  	if(debug['M'])
   652  		print("gmove %lN -> %lN\n", f, t);
   653  
   654  	ft = simsimtype(f->type);
   655  	tt = simsimtype(t->type);
   656  	cvt = t->type;
   657  
   658  	if(iscomplex[ft] || iscomplex[tt]) {
   659  		complexmove(f, t);
   660  		return;
   661  	}
   662  
   663  	// cannot have two memory operands
   664  	if(ismem(f) && ismem(t))
   665  		goto hard;
   666  
   667  	// convert constant to desired type
   668  	if(f->op == OLITERAL) {
   669  		switch(tt) {
   670  		default:
   671  			convconst(&con, t->type, &f->val);
   672  			break;
   673  
   674  		case TINT32:
   675  		case TINT16:
   676  		case TINT8:
   677  			convconst(&con, types[TINT64], &f->val);
   678  			regalloc(&r1, con.type, t);
   679  			gins(AMOVD, &con, &r1);
   680  			gmove(&r1, t);
   681  			regfree(&r1);
   682  			return;
   683  
   684  		case TUINT32:
   685  		case TUINT16:
   686  		case TUINT8:
   687  			convconst(&con, types[TUINT64], &f->val);
   688  			regalloc(&r1, con.type, t);
   689  			gins(AMOVD, &con, &r1);
   690  			gmove(&r1, t);
   691  			regfree(&r1);
   692  			return;
   693  		}
   694  
   695  		f = &con;
   696  		ft = tt;	// so big switch will choose a simple mov
   697  
   698  		// constants can't move directly to memory.
   699  		if(ismem(t)) {
   700  			goto hard;
   701  			// float constants come from memory.
   702  			//if(isfloat[tt])
   703  			//	goto hard;
   704  
   705  			// 64-bit immediates are also from memory.
   706  			//if(isint[tt])
   707  			//	goto hard;
   708  			//// 64-bit immediates are really 32-bit sign-extended
   709  			//// unless moving into a register.
   710  			//if(isint[tt]) {
   711  			//	if(mpcmpfixfix(con.val.u.xval, minintval[TINT32]) < 0)
   712  			//		goto hard;
   713  			//	if(mpcmpfixfix(con.val.u.xval, maxintval[TINT32]) > 0)
   714  			//		goto hard;
   715  			//}
   716  		}
   717  	}
   718  
   719  	// value -> value copy, only one memory operand.
   720  	// figure out the instruction to use.
   721  	// break out of switch for one-instruction gins.
   722  	// goto rdst for "destination must be register".
   723  	// goto hard for "convert to cvt type first".
   724  	// otherwise handle and return.
   725  
   726  	switch(CASE(ft, tt)) {
   727  	default:
   728  		fatal("gmove %lT -> %lT", f->type, t->type);
   729  
   730  	/*
   731  	 * integer copy and truncate
   732  	 */
   733  	case CASE(TINT8, TINT8):	// same size
   734  	case CASE(TUINT8, TINT8):
   735  	case CASE(TINT16, TINT8):	// truncate
   736  	case CASE(TUINT16, TINT8):
   737  	case CASE(TINT32, TINT8):
   738  	case CASE(TUINT32, TINT8):
   739  	case CASE(TINT64, TINT8):
   740  	case CASE(TUINT64, TINT8):
   741  		a = AMOVB;
   742  		break;
   743  
   744  	case CASE(TINT8, TUINT8):	// same size
   745  	case CASE(TUINT8, TUINT8):
   746  	case CASE(TINT16, TUINT8):	// truncate
   747  	case CASE(TUINT16, TUINT8):
   748  	case CASE(TINT32, TUINT8):
   749  	case CASE(TUINT32, TUINT8):
   750  	case CASE(TINT64, TUINT8):
   751  	case CASE(TUINT64, TUINT8):
   752  		a = AMOVBZ;
   753  		break;
   754  
   755  	case CASE(TINT16, TINT16):	// same size
   756  	case CASE(TUINT16, TINT16):
   757  	case CASE(TINT32, TINT16):	// truncate
   758  	case CASE(TUINT32, TINT16):
   759  	case CASE(TINT64, TINT16):
   760  	case CASE(TUINT64, TINT16):
   761  		a = AMOVH;
   762  		break;
   763  
   764  	case CASE(TINT16, TUINT16):	// same size
   765  	case CASE(TUINT16, TUINT16):
   766  	case CASE(TINT32, TUINT16):	// truncate
   767  	case CASE(TUINT32, TUINT16):
   768  	case CASE(TINT64, TUINT16):
   769  	case CASE(TUINT64, TUINT16):
   770  		a = AMOVHZ;
   771  		break;
   772  
   773  	case CASE(TINT32, TINT32):	// same size
   774  	case CASE(TUINT32, TINT32):
   775  	case CASE(TINT64, TINT32):	// truncate
   776  	case CASE(TUINT64, TINT32):
   777  		a = AMOVW;
   778  		break;
   779  
   780  	case CASE(TINT32, TUINT32):	// same size
   781  	case CASE(TUINT32, TUINT32):
   782  	case CASE(TINT64, TUINT32):
   783  	case CASE(TUINT64, TUINT32):
   784  		a = AMOVWZ;
   785  		break;
   786  
   787  	case CASE(TINT64, TINT64):	// same size
   788  	case CASE(TINT64, TUINT64):
   789  	case CASE(TUINT64, TINT64):
   790  	case CASE(TUINT64, TUINT64):
   791  		a = AMOVD;
   792  		break;
   793  
   794  	/*
   795  	 * integer up-conversions
   796  	 */
   797  	case CASE(TINT8, TINT16):	// sign extend int8
   798  	case CASE(TINT8, TUINT16):
   799  	case CASE(TINT8, TINT32):
   800  	case CASE(TINT8, TUINT32):
   801  	case CASE(TINT8, TINT64):
   802  	case CASE(TINT8, TUINT64):
   803  		a = AMOVB;
   804  		goto rdst;
   805  
   806  	case CASE(TUINT8, TINT16):	// zero extend uint8
   807  	case CASE(TUINT8, TUINT16):
   808  	case CASE(TUINT8, TINT32):
   809  	case CASE(TUINT8, TUINT32):
   810  	case CASE(TUINT8, TINT64):
   811  	case CASE(TUINT8, TUINT64):
   812  		a = AMOVBZ;
   813  		goto rdst;
   814  
   815  	case CASE(TINT16, TINT32):	// sign extend int16
   816  	case CASE(TINT16, TUINT32):
   817  	case CASE(TINT16, TINT64):
   818  	case CASE(TINT16, TUINT64):
   819  		a = AMOVH;
   820  		goto rdst;
   821  
   822  	case CASE(TUINT16, TINT32):	// zero extend uint16
   823  	case CASE(TUINT16, TUINT32):
   824  	case CASE(TUINT16, TINT64):
   825  	case CASE(TUINT16, TUINT64):
   826  		a = AMOVHZ;
   827  		goto rdst;
   828  
   829  	case CASE(TINT32, TINT64):	// sign extend int32
   830  	case CASE(TINT32, TUINT64):
   831  		a = AMOVW;
   832  		goto rdst;
   833  
   834  	case CASE(TUINT32, TINT64):	// zero extend uint32
   835  	case CASE(TUINT32, TUINT64):
   836  		a = AMOVWZ;
   837  		goto rdst;
   838  
   839  	/*
   840  	* float to integer
   841  	*/
   842  	case CASE(TFLOAT32, TINT32):
   843  	case CASE(TFLOAT64, TINT32):
   844  	case CASE(TFLOAT32, TINT64):
   845  	case CASE(TFLOAT64, TINT64):
   846  	case CASE(TFLOAT32, TINT16):
   847  	case CASE(TFLOAT32, TINT8):
   848  	case CASE(TFLOAT32, TUINT16):
   849  	case CASE(TFLOAT32, TUINT8):
   850  	case CASE(TFLOAT64, TINT16):
   851  	case CASE(TFLOAT64, TINT8):
   852  	case CASE(TFLOAT64, TUINT16):
   853  	case CASE(TFLOAT64, TUINT8):
   854  	case CASE(TFLOAT32, TUINT32):
   855  	case CASE(TFLOAT64, TUINT32):
   856  	case CASE(TFLOAT32, TUINT64):
   857  	case CASE(TFLOAT64, TUINT64):
   858  		//warn("gmove: convert float to int not implemented: %N -> %N\n", f, t);
   859  		//return;
   860  		// algorithm is:
   861  		//	if small enough, use native float64 -> int64 conversion.
   862  		//	otherwise, subtract 2^63, convert, and add it back.
   863  		bignodes();
   864  		regalloc(&r1, types[ft], f);
   865  		gmove(f, &r1);
   866  		if(tt == TUINT64) {
   867  			regalloc(&r2, types[TFLOAT64], N);
   868  			gmove(&bigf, &r2);
   869  			gins(AFCMPU, &r1, &r2);
   870  			p1 = gbranch(optoas(OLT, types[TFLOAT64]), T, +1);
   871  			gins(AFSUB, &r2, &r1);
   872  			patch(p1, pc);
   873  			regfree(&r2);
   874  		}
   875  		regalloc(&r2, types[TFLOAT64], N);
   876  		regalloc(&r3, types[TINT64], t);
   877  		gins(AFCTIDZ, &r1, &r2);
   878  		p1 = gins(AFMOVD, &r2, N);
   879  		p1->to.type = D_OREG;
   880  		p1->to.reg = REGSP;
   881  		p1->to.offset = -8;
   882  		p1 = gins(AMOVD, N, &r3);
   883  		p1->from.type = D_OREG;
   884  		p1->from.reg = REGSP;
   885  		p1->from.offset = -8;
   886  		regfree(&r2);
   887  		regfree(&r1);
   888  		if(tt == TUINT64) {
   889  			p1 = gbranch(optoas(OLT, types[TFLOAT64]), T, +1); // use CR0 here again
   890  			nodreg(&r1, types[TINT64], D_R0+REGTMP);
   891  			gins(AMOVD, &bigi, &r1);
   892  			gins(AADD, &r1, &r3);
   893  			patch(p1, pc);
   894  		}
   895  		gmove(&r3, t);
   896  		regfree(&r3);
   897  		return;
   898  
   899  	/*
   900  	 * integer to float
   901  	 */
   902  	case CASE(TINT32, TFLOAT32):
   903  	case CASE(TINT32, TFLOAT64):
   904  	case CASE(TINT64, TFLOAT32):
   905  	case CASE(TINT64, TFLOAT64):
   906  	case CASE(TINT16, TFLOAT32):
   907  	case CASE(TINT16, TFLOAT64):
   908  	case CASE(TINT8, TFLOAT32):
   909  	case CASE(TINT8, TFLOAT64):
   910  	case CASE(TUINT16, TFLOAT32):
   911  	case CASE(TUINT16, TFLOAT64):
   912  	case CASE(TUINT8, TFLOAT32):
   913  	case CASE(TUINT8, TFLOAT64):
   914  	case CASE(TUINT32, TFLOAT32):
   915  	case CASE(TUINT32, TFLOAT64):
   916  	case CASE(TUINT64, TFLOAT32):
   917  	case CASE(TUINT64, TFLOAT64):
   918  		//warn("gmove: convert int to float not implemented: %N -> %N\n", f, t);
   919  		//return;
   920  		// algorithm is:
   921  		//	if small enough, use native int64 -> uint64 conversion.
   922  		//	otherwise, halve (rounding to odd?), convert, and double.
   923  		bignodes();
   924  		regalloc(&r1, types[TINT64], N);
   925  		gmove(f, &r1);
   926  		if(ft == TUINT64) {
   927  			nodreg(&r2, types[TUINT64], D_R0+REGTMP);
   928  			gmove(&bigi, &r2);
   929  			gins(ACMPU, &r1, &r2);
   930  			p1 = gbranch(optoas(OLT, types[TUINT64]), T, +1);
   931  			p2 = gins(ASRD, N, &r1);
   932  			p2->from.type = D_CONST;
   933  			p2->from.offset = 1;
   934  			patch(p1, pc);
   935  		}
   936  		regalloc(&r2, types[TFLOAT64], t);
   937  		p1 = gins(AMOVD, &r1, N);
   938  		p1->to.type = D_OREG;
   939  		p1->to.reg = REGSP;
   940  		p1->to.offset = -8;
   941  		p1 = gins(AFMOVD, N, &r2);
   942  		p1->from.type = D_OREG;
   943  		p1->from.reg = REGSP;
   944  		p1->from.offset = -8;
   945  		gins(AFCFID, &r2, &r2);
   946  		regfree(&r1);
   947  		if(ft == TUINT64) {
   948  			p1 = gbranch(optoas(OLT, types[TUINT64]), T, +1); // use CR0 here again
   949  			nodreg(&r1, types[TFLOAT64], D_F0+FREGTWO);
   950  			gins(AFMUL, &r1, &r2);
   951  			patch(p1, pc);
   952  		}
   953  		gmove(&r2, t);
   954  		regfree(&r2);
   955  		return;
   956  
   957  	/*
   958  	 * float to float
   959  	 */
   960  	case CASE(TFLOAT32, TFLOAT32):
   961  		a = AFMOVS;
   962  		break;
   963  
   964  	case CASE(TFLOAT64, TFLOAT64):
   965  		a = AFMOVD;
   966  		break;
   967  
   968  	case CASE(TFLOAT32, TFLOAT64):
   969  		a = AFMOVS;
   970  		goto rdst;
   971  
   972  	case CASE(TFLOAT64, TFLOAT32):
   973  		a = AFRSP;
   974  		goto rdst;
   975  	}
   976  
   977  	gins(a, f, t);
   978  	return;
   979  
   980  rdst:
   981  	// requires register destination
   982  	regalloc(&r1, t->type, t);
   983  	gins(a, f, &r1);
   984  	gmove(&r1, t);
   985  	regfree(&r1);
   986  	return;
   987  
   988  hard:
   989  	// requires register intermediate
   990  	regalloc(&r1, cvt, t);
   991  	gmove(f, &r1);
   992  	gmove(&r1, t);
   993  	regfree(&r1);
   994  	return;
   995  }
   996  
   997  /*
   998   * generate one instruction:
   999   *	as f, t
  1000   */
  1001  Prog*
  1002  gins(int as, Node *f, Node *t)
  1003  {
  1004  	int32 w;
  1005  	Prog *p;
  1006  	Addr af, at;
  1007  
  1008  	// TODO(austin): Add self-move test like in 6g (but be careful
  1009  	// of truncation moves)
  1010  
  1011  	memset(&af, 0, sizeof af);
  1012  	memset(&at, 0, sizeof at);
  1013  	if(f != N)
  1014  		naddr(f, &af, 1);
  1015  	if(t != N)
  1016  		naddr(t, &at, 1);
  1017  	p = prog(as);
  1018  	if(f != N)
  1019  		p->from = af;
  1020  	if(t != N)
  1021  		p->to = at;
  1022  	if(as == ATEXT)
  1023  		p->reg = 0;
  1024  	if(debug['g'])
  1025  		print("%P\n", p);
  1026  
  1027  	w = 0;
  1028  	switch(as) {
  1029  	case AMOVB:
  1030  	case AMOVBU:
  1031  	case AMOVBZ:
  1032  	case AMOVBZU:
  1033  		w = 1;
  1034  		break;
  1035  	case AMOVH:
  1036  	case AMOVHU:
  1037  	case AMOVHZ:
  1038  	case AMOVHZU:
  1039  		w = 2;
  1040  		break;
  1041  	case AMOVW:
  1042  	case AMOVWU:
  1043  	case AMOVWZ:
  1044  	case AMOVWZU:
  1045  		w = 4;
  1046  		break;
  1047  	case AMOVD:
  1048  	case AMOVDU:
  1049  		if(af.type == D_CONST)
  1050  			break;
  1051  		w = 8;
  1052  		break;
  1053  	}
  1054  	if(w != 0 && ((f != N && af.width < w) || (t != N && at.type != D_REG && at.width > w))) {
  1055  		dump("f", f);
  1056  		dump("t", t);
  1057  		fatal("bad width: %P (%d, %d)\n", p, af.width, at.width);
  1058  	}
  1059  
  1060  	return p;
  1061  }
  1062  
  1063  void
  1064  fixlargeoffset(Node *n)
  1065  {
  1066  	Node a;
  1067  
  1068  	if(n == N)
  1069  		return;
  1070  	if(n->op != OINDREG)
  1071  		return;
  1072  	if(n->val.u.reg == D_R0+REGSP) // stack offset cannot be large
  1073  		return;
  1074  	if(n->xoffset != (int32)n->xoffset) {
  1075  		// TODO(minux): offset too large, move into R31 and add to R31 instead.
  1076  		// this is used only in test/fixedbugs/issue6036.go.
  1077  		print("offset too large: %N\n", n);
  1078  		noimpl;
  1079  		a = *n;
  1080  		a.op = OREGISTER;
  1081  		a.type = types[tptr];
  1082  		a.xoffset = 0;
  1083  		cgen_checknil(&a);
  1084  		ginscon(optoas(OADD, types[tptr]), n->xoffset, &a);
  1085  		n->xoffset = 0;
  1086  	}
  1087  }
  1088  
  1089  /*
  1090   * generate code to compute n;
  1091   * make a refer to result.
  1092   */
  1093  void
  1094  naddr(Node *n, Addr *a, int canemitcode)
  1095  {
  1096  	Sym *s;
  1097  
  1098  	a->type = D_NONE;
  1099  	a->name = D_NONE;
  1100  	a->reg = NREG;
  1101  	a->gotype = nil;
  1102  	a->node = N;
  1103  	a->etype = 0;
  1104  	a->width = 0;
  1105  	if(n == N)
  1106  		return;
  1107  
  1108  	if(n->type != T && n->type->etype != TIDEAL) {
  1109  		dowidth(n->type);
  1110  		a->width = n->type->width;
  1111  	}
  1112  
  1113  	switch(n->op) {
  1114  	default:
  1115  		fatal("naddr: bad %O %D", n->op, a);
  1116  		break;
  1117  
  1118  	case ONAME:
  1119  		a->etype = 0;
  1120  		a->reg = NREG;
  1121  		if(n->type != T)
  1122  			a->etype = simtype[n->type->etype];
  1123  		a->offset = n->xoffset;
  1124  		s = n->sym;
  1125  		a->node = n->orig;
  1126  		//if(a->node >= (Node*)&n)
  1127  		//	fatal("stack node");
  1128  		if(s == S)
  1129  			s = lookup(".noname");
  1130  		if(n->method) {
  1131  			if(n->type != T)
  1132  			if(n->type->sym != S)
  1133  			if(n->type->sym->pkg != nil)
  1134  				s = pkglookup(s->name, n->type->sym->pkg);
  1135  		}
  1136  
  1137  		a->type = D_OREG;
  1138  		switch(n->class) {
  1139  		default:
  1140  			fatal("naddr: ONAME class %S %d\n", n->sym, n->class);
  1141  		case PEXTERN:
  1142  			a->name = D_EXTERN;
  1143  			break;
  1144  		case PAUTO:
  1145  			a->name = D_AUTO;
  1146  			break;
  1147  		case PPARAM:
  1148  		case PPARAMOUT:
  1149  			a->name = D_PARAM;
  1150  			break;
  1151  		case PFUNC:
  1152  			a->name = D_EXTERN;
  1153  			a->type = D_CONST;
  1154  			a->width = widthptr;
  1155  			s = funcsym(s);
  1156  			break;
  1157  		}
  1158  		a->sym = linksym(s);
  1159  		break;
  1160  
  1161  	case OLITERAL:
  1162  		switch(n->val.ctype) {
  1163  		default:
  1164  			fatal("naddr: const %lT", n->type);
  1165  			break;
  1166  		case CTFLT:
  1167  			a->type = D_FCONST;
  1168  			a->u.dval = mpgetflt(n->val.u.fval);
  1169  			break;
  1170  		case CTINT:
  1171  		case CTRUNE:
  1172  			a->sym = nil;
  1173  			a->type = D_CONST;
  1174  			a->offset = mpgetfix(n->val.u.xval);
  1175  			break;
  1176  		case CTSTR:
  1177  			datagostring(n->val.u.sval, a);
  1178  			break;
  1179  		case CTBOOL:
  1180  			a->sym = nil;
  1181  			a->type = D_CONST;
  1182  			a->offset = n->val.u.bval;
  1183  			break;
  1184  		case CTNIL:
  1185  			a->sym = nil;
  1186  			a->type = D_CONST;
  1187  			a->offset = 0;
  1188  			break;
  1189  		}
  1190  		break;
  1191  
  1192  	case OREGISTER:
  1193  		if(n->val.u.reg < D_F0) {
  1194  			a->type = D_REG;
  1195  			a->reg = n->val.u.reg;
  1196  		} else {
  1197  			a->type = D_FREG;
  1198  			a->reg = n->val.u.reg - D_F0;
  1199  		}
  1200  		a->sym = nil;
  1201  		break;
  1202  
  1203  	case OINDREG:
  1204  		a->type = D_OREG;
  1205  		a->reg = n->val.u.reg;
  1206  		a->sym = linksym(n->sym);
  1207  		a->offset = n->xoffset;
  1208  		if(a->offset != (int32)a->offset)
  1209  			yyerror("offset %lld too large for OINDREG", a->offset);
  1210  		break;
  1211  
  1212  	case OPARAM:
  1213  		// n->left is PHEAP ONAME for stack parameter.
  1214  		// compute address of actual parameter on stack.
  1215  		a->etype = simtype[n->left->type->etype];
  1216  		a->width = n->left->type->width;
  1217  		a->offset = n->xoffset;
  1218  		a->sym = linksym(n->left->sym);
  1219  		a->type = D_OREG;
  1220  		a->name = D_PARAM;
  1221  		a->node = n->left->orig;
  1222  		break;
  1223  
  1224  	case OCLOSUREVAR:
  1225  		if(!curfn->needctxt)
  1226  			fatal("closurevar without needctxt");
  1227  		a->type = D_OREG;
  1228  		a->reg = REGENV;
  1229  		a->offset = n->xoffset;
  1230  		a->sym = nil;
  1231  		break;
  1232  
  1233  	case OCFUNC:
  1234  		naddr(n->left, a, canemitcode);
  1235  		a->sym = linksym(n->left->sym);
  1236  		break;
  1237  
  1238  	case OITAB:
  1239  		// itable of interface value
  1240  		naddr(n->left, a, canemitcode);
  1241  		a->etype = simtype[tptr];
  1242  		if(a->type == D_CONST && a->offset == 0)
  1243  			break;	// itab(nil)
  1244  		a->width = widthptr;
  1245  		break;
  1246  
  1247  	case OSPTR:
  1248  		// pointer in a string or slice
  1249  		naddr(n->left, a, canemitcode);
  1250  		a->etype = simtype[tptr];
  1251  		if(a->type == D_CONST && a->offset == 0)
  1252  			break;	// ptr(nil)
  1253  		a->offset += Array_array;
  1254  		a->width = widthptr;
  1255  		break;
  1256  
  1257  	case OLEN:
  1258  		// len of string or slice
  1259  		naddr(n->left, a, canemitcode);
  1260  		a->etype = simtype[TINT];
  1261  		if(a->type == D_CONST && a->offset == 0)
  1262  			break;	// len(nil)
  1263  		a->offset += Array_nel;
  1264  		a->width = widthint;
  1265  		break;
  1266  
  1267  	case OCAP:
  1268  		// cap of string or slice
  1269  		naddr(n->left, a, canemitcode);
  1270  		a->etype = simtype[TINT];
  1271  		if(a->type == D_CONST && a->offset == 0)
  1272  			break;	// cap(nil)
  1273  		a->offset += Array_cap;
  1274  		a->width = widthint;
  1275  		break;
  1276  
  1277  	case OADDR:
  1278  		naddr(n->left, a, canemitcode);
  1279  		a->etype = tptr;
  1280  		switch(a->type) {
  1281  		case D_OREG:
  1282  			a->type = D_CONST;
  1283  			break;
  1284  
  1285  		case D_REG:
  1286  		case D_CONST:
  1287  			break;
  1288  
  1289  		default:
  1290  			fatal("naddr: OADDR %d\n", a->type);
  1291  		}
  1292  		break;
  1293  	}
  1294  }
  1295  
  1296  /*
  1297   * return Axxx for Oxxx on type t.
  1298   */
  1299  int
  1300  optoas(int op, Type *t)
  1301  {
  1302  	int a;
  1303  
  1304  	if(t == T)
  1305  		fatal("optoas: t is nil");
  1306  
  1307  	a = AGOK;
  1308  	switch(CASE(op, simtype[t->etype])) {
  1309  	default:
  1310  		fatal("optoas: no entry for op=%O type=%T", op, t);
  1311  		break;
  1312  
  1313  	case CASE(OEQ, TBOOL):
  1314  	case CASE(OEQ, TINT8):
  1315  	case CASE(OEQ, TUINT8):
  1316  	case CASE(OEQ, TINT16):
  1317  	case CASE(OEQ, TUINT16):
  1318  	case CASE(OEQ, TINT32):
  1319  	case CASE(OEQ, TUINT32):
  1320  	case CASE(OEQ, TINT64):
  1321  	case CASE(OEQ, TUINT64):
  1322  	case CASE(OEQ, TPTR32):
  1323  	case CASE(OEQ, TPTR64):
  1324  	case CASE(OEQ, TFLOAT32):
  1325  	case CASE(OEQ, TFLOAT64):
  1326  		a = ABEQ;
  1327  		break;
  1328  
  1329  	case CASE(ONE, TBOOL):
  1330  	case CASE(ONE, TINT8):
  1331  	case CASE(ONE, TUINT8):
  1332  	case CASE(ONE, TINT16):
  1333  	case CASE(ONE, TUINT16):
  1334  	case CASE(ONE, TINT32):
  1335  	case CASE(ONE, TUINT32):
  1336  	case CASE(ONE, TINT64):
  1337  	case CASE(ONE, TUINT64):
  1338  	case CASE(ONE, TPTR32):
  1339  	case CASE(ONE, TPTR64):
  1340  	case CASE(ONE, TFLOAT32):
  1341  	case CASE(ONE, TFLOAT64):
  1342  		a = ABNE;
  1343  		break;
  1344  
  1345  	case CASE(OLT, TINT8):	// ACMP
  1346  	case CASE(OLT, TINT16):
  1347  	case CASE(OLT, TINT32):
  1348  	case CASE(OLT, TINT64):
  1349  	case CASE(OLT, TUINT8):	// ACMPU
  1350  	case CASE(OLT, TUINT16):
  1351  	case CASE(OLT, TUINT32):
  1352  	case CASE(OLT, TUINT64):
  1353  	case CASE(OLT, TFLOAT32): // AFCMPU
  1354  	case CASE(OLT, TFLOAT64):
  1355  		a = ABLT;
  1356  		break;
  1357  
  1358  	case CASE(OLE, TINT8):	// ACMP
  1359  	case CASE(OLE, TINT16):
  1360  	case CASE(OLE, TINT32):
  1361  	case CASE(OLE, TINT64):
  1362  	case CASE(OLE, TUINT8):	// ACMPU
  1363  	case CASE(OLE, TUINT16):
  1364  	case CASE(OLE, TUINT32):
  1365  	case CASE(OLE, TUINT64):
  1366  	case CASE(OLE, TFLOAT32): // AFCMPU
  1367  	case CASE(OLE, TFLOAT64):
  1368  		a = ABLE;
  1369  		break;
  1370  
  1371  	case CASE(OGT, TINT8):
  1372  	case CASE(OGT, TINT16):
  1373  	case CASE(OGT, TINT32):
  1374  	case CASE(OGT, TINT64):
  1375  	case CASE(OGT, TUINT8):
  1376  	case CASE(OGT, TUINT16):
  1377  	case CASE(OGT, TUINT32):
  1378  	case CASE(OGT, TUINT64):
  1379  	case CASE(OGT, TFLOAT32):
  1380  	case CASE(OGT, TFLOAT64):
  1381  		a = ABGT;
  1382  		break;
  1383  
  1384  	case CASE(OGE, TINT8):
  1385  	case CASE(OGE, TINT16):
  1386  	case CASE(OGE, TINT32):
  1387  	case CASE(OGE, TINT64):
  1388  	case CASE(OGE, TUINT8):
  1389  	case CASE(OGE, TUINT16):
  1390  	case CASE(OGE, TUINT32):
  1391  	case CASE(OGE, TUINT64):
  1392  	case CASE(OGE, TFLOAT32):
  1393  	case CASE(OGE, TFLOAT64):
  1394  		a = ABGE;
  1395  		break;
  1396  
  1397  	case CASE(OCMP, TBOOL):
  1398  	case CASE(OCMP, TINT8):
  1399  	case CASE(OCMP, TINT16):
  1400  	case CASE(OCMP, TINT32):
  1401  	case CASE(OCMP, TPTR32):
  1402  	case CASE(OCMP, TINT64):
  1403  		a = ACMP;
  1404  		break;
  1405  
  1406  	case CASE(OCMP, TUINT8):
  1407  	case CASE(OCMP, TUINT16):
  1408  	case CASE(OCMP, TUINT32):
  1409  	case CASE(OCMP, TUINT64):
  1410  	case CASE(OCMP, TPTR64):
  1411  		a = ACMPU;
  1412  		break;
  1413  
  1414  	case CASE(OCMP, TFLOAT32):
  1415  	case CASE(OCMP, TFLOAT64):
  1416  		a = AFCMPU;
  1417  		break;
  1418  
  1419  	case CASE(OAS, TBOOL):
  1420  	case CASE(OAS, TINT8):
  1421  		a = AMOVB;
  1422  		break;
  1423  
  1424  	case CASE(OAS, TUINT8):
  1425  		a = AMOVBZ;
  1426  		break;
  1427  
  1428  	case CASE(OAS, TINT16):
  1429  		a = AMOVH;
  1430  		break;
  1431  
  1432  	case CASE(OAS, TUINT16):
  1433  		a = AMOVHZ;
  1434  		break;
  1435  
  1436  	case CASE(OAS, TINT32):
  1437  		a = AMOVW;
  1438  		break;
  1439  
  1440  	case CASE(OAS, TUINT32):
  1441  	case CASE(OAS, TPTR32):
  1442  		a = AMOVWZ;
  1443  		break;
  1444  
  1445  	case CASE(OAS, TINT64):
  1446  	case CASE(OAS, TUINT64):
  1447  	case CASE(OAS, TPTR64):
  1448  		a = AMOVD;
  1449  		break;
  1450  
  1451  	case CASE(OAS, TFLOAT32):
  1452  		a = AFMOVS;
  1453  		break;
  1454  
  1455  	case CASE(OAS, TFLOAT64):
  1456  		a = AFMOVD;
  1457  		break;
  1458  
  1459  	case CASE(OADD, TINT8):
  1460  	case CASE(OADD, TUINT8):
  1461  	case CASE(OADD, TINT16):
  1462  	case CASE(OADD, TUINT16):
  1463  	case CASE(OADD, TINT32):
  1464  	case CASE(OADD, TUINT32):
  1465  	case CASE(OADD, TPTR32):
  1466  	case CASE(OADD, TINT64):
  1467  	case CASE(OADD, TUINT64):
  1468  	case CASE(OADD, TPTR64):
  1469  		a = AADD;
  1470  		break;
  1471  
  1472  	case CASE(OADD, TFLOAT32):
  1473  		a = AFADDS;
  1474  		break;
  1475  
  1476  	case CASE(OADD, TFLOAT64):
  1477  		a = AFADD;
  1478  		break;
  1479  
  1480  	case CASE(OSUB, TINT8):
  1481  	case CASE(OSUB, TUINT8):
  1482  	case CASE(OSUB, TINT16):
  1483  	case CASE(OSUB, TUINT16):
  1484  	case CASE(OSUB, TINT32):
  1485  	case CASE(OSUB, TUINT32):
  1486  	case CASE(OSUB, TPTR32):
  1487  	case CASE(OSUB, TINT64):
  1488  	case CASE(OSUB, TUINT64):
  1489  	case CASE(OSUB, TPTR64):
  1490  		a = ASUB;
  1491  		break;
  1492  
  1493  	case CASE(OSUB, TFLOAT32):
  1494  		a = AFSUBS;
  1495  		break;
  1496  
  1497  	case CASE(OSUB, TFLOAT64):
  1498  		a = AFSUB;
  1499  		break;
  1500  
  1501  	case CASE(OMINUS, TINT8):
  1502  	case CASE(OMINUS, TUINT8):
  1503  	case CASE(OMINUS, TINT16):
  1504  	case CASE(OMINUS, TUINT16):
  1505  	case CASE(OMINUS, TINT32):
  1506  	case CASE(OMINUS, TUINT32):
  1507  	case CASE(OMINUS, TPTR32):
  1508  	case CASE(OMINUS, TINT64):
  1509  	case CASE(OMINUS, TUINT64):
  1510  	case CASE(OMINUS, TPTR64):
  1511  		a = ANEG;
  1512  		break;
  1513  
  1514  	case CASE(OAND, TINT8):
  1515  	case CASE(OAND, TUINT8):
  1516  	case CASE(OAND, TINT16):
  1517  	case CASE(OAND, TUINT16):
  1518  	case CASE(OAND, TINT32):
  1519  	case CASE(OAND, TUINT32):
  1520  	case CASE(OAND, TPTR32):
  1521  	case CASE(OAND, TINT64):
  1522  	case CASE(OAND, TUINT64):
  1523  	case CASE(OAND, TPTR64):
  1524  		a = AAND;
  1525  		break;
  1526  
  1527  	case CASE(OOR, TINT8):
  1528  	case CASE(OOR, TUINT8):
  1529  	case CASE(OOR, TINT16):
  1530  	case CASE(OOR, TUINT16):
  1531  	case CASE(OOR, TINT32):
  1532  	case CASE(OOR, TUINT32):
  1533  	case CASE(OOR, TPTR32):
  1534  	case CASE(OOR, TINT64):
  1535  	case CASE(OOR, TUINT64):
  1536  	case CASE(OOR, TPTR64):
  1537  		a = AOR;
  1538  		break;
  1539  
  1540  	case CASE(OXOR, TINT8):
  1541  	case CASE(OXOR, TUINT8):
  1542  	case CASE(OXOR, TINT16):
  1543  	case CASE(OXOR, TUINT16):
  1544  	case CASE(OXOR, TINT32):
  1545  	case CASE(OXOR, TUINT32):
  1546  	case CASE(OXOR, TPTR32):
  1547  	case CASE(OXOR, TINT64):
  1548  	case CASE(OXOR, TUINT64):
  1549  	case CASE(OXOR, TPTR64):
  1550  		a = AXOR;
  1551  		break;
  1552  
  1553  	// TODO(minux): handle rotates
  1554  	//case CASE(OLROT, TINT8):
  1555  	//case CASE(OLROT, TUINT8):
  1556  	//case CASE(OLROT, TINT16):
  1557  	//case CASE(OLROT, TUINT16):
  1558  	//case CASE(OLROT, TINT32):
  1559  	//case CASE(OLROT, TUINT32):
  1560  	//case CASE(OLROT, TPTR32):
  1561  	//case CASE(OLROT, TINT64):
  1562  	//case CASE(OLROT, TUINT64):
  1563  	//case CASE(OLROT, TPTR64):
  1564  	//	a = 0//???; RLDC?
  1565  	//	break;
  1566  
  1567  	case CASE(OLSH, TINT8):
  1568  	case CASE(OLSH, TUINT8):
  1569  	case CASE(OLSH, TINT16):
  1570  	case CASE(OLSH, TUINT16):
  1571  	case CASE(OLSH, TINT32):
  1572  	case CASE(OLSH, TUINT32):
  1573  	case CASE(OLSH, TPTR32):
  1574  	case CASE(OLSH, TINT64):
  1575  	case CASE(OLSH, TUINT64):
  1576  	case CASE(OLSH, TPTR64):
  1577  		a = ASLD;
  1578  		break;
  1579  
  1580  	case CASE(ORSH, TUINT8):
  1581  	case CASE(ORSH, TUINT16):
  1582  	case CASE(ORSH, TUINT32):
  1583  	case CASE(ORSH, TPTR32):
  1584  	case CASE(ORSH, TUINT64):
  1585  	case CASE(ORSH, TPTR64):
  1586  		a = ASRD;
  1587  		break;
  1588  
  1589  	case CASE(ORSH, TINT8):
  1590  	case CASE(ORSH, TINT16):
  1591  	case CASE(ORSH, TINT32):
  1592  	case CASE(ORSH, TINT64):
  1593  		a = ASRAD;
  1594  		break;
  1595  
  1596  	// TODO(minux): handle rotates
  1597  	//case CASE(ORROTC, TINT8):
  1598  	//case CASE(ORROTC, TUINT8):
  1599  	//case CASE(ORROTC, TINT16):
  1600  	//case CASE(ORROTC, TUINT16):
  1601  	//case CASE(ORROTC, TINT32):
  1602  	//case CASE(ORROTC, TUINT32):
  1603  	//case CASE(ORROTC, TINT64):
  1604  	//case CASE(ORROTC, TUINT64):
  1605  	//	a = 0//??? RLDC??
  1606  	//	break;
  1607  
  1608  	case CASE(OHMUL, TINT64):
  1609  		a = AMULHD;
  1610  		break;
  1611  	case CASE(OHMUL, TUINT64):
  1612  	case CASE(OHMUL, TPTR64):
  1613  		a = AMULHDU;
  1614  		break;
  1615  
  1616  	case CASE(OMUL, TINT8):
  1617  	case CASE(OMUL, TINT16):
  1618  	case CASE(OMUL, TINT32):
  1619  	case CASE(OMUL, TINT64):
  1620  		a = AMULLD;
  1621  		break;
  1622  
  1623  	case CASE(OMUL, TUINT8):
  1624  	case CASE(OMUL, TUINT16):
  1625  	case CASE(OMUL, TUINT32):
  1626  	case CASE(OMUL, TPTR32):
  1627  		// don't use word multiply, the high 32-bit are undefined.
  1628  		// fallthrough
  1629  	case CASE(OMUL, TUINT64):
  1630  	case CASE(OMUL, TPTR64):
  1631  		a = AMULLD; // for 64-bit multiplies, signedness doesn't matter.
  1632  		break;
  1633  
  1634  	case CASE(OMUL, TFLOAT32):
  1635  		a = AFMULS;
  1636  		break;
  1637  
  1638  	case CASE(OMUL, TFLOAT64):
  1639  		a = AFMUL;
  1640  		break;
  1641  
  1642  	case CASE(ODIV, TINT8):
  1643  	case CASE(ODIV, TINT16):
  1644  	case CASE(ODIV, TINT32):
  1645  	case CASE(ODIV, TINT64):
  1646  		a = ADIVD;
  1647  		break;
  1648  
  1649  	case CASE(ODIV, TUINT8):
  1650  	case CASE(ODIV, TUINT16):
  1651  	case CASE(ODIV, TUINT32):
  1652  	case CASE(ODIV, TPTR32):
  1653  	case CASE(ODIV, TUINT64):
  1654  	case CASE(ODIV, TPTR64):
  1655  		a = ADIVDU;
  1656  		break;
  1657  
  1658  	case CASE(ODIV, TFLOAT32):
  1659  		a = AFDIVS;
  1660  		break;
  1661  
  1662  	case CASE(ODIV, TFLOAT64):
  1663  		a = AFDIV;
  1664  		break;
  1665  
  1666  	}
  1667  	return a;
  1668  }
  1669  
  1670  enum
  1671  {
  1672  	ODynam		= 1<<0,
  1673  	OAddable	= 1<<1,
  1674  };
  1675  
  1676  int
  1677  xgen(Node *n, Node *a, int o)
  1678  {
  1679  	// TODO(minux)
  1680  	USED(n); USED(a); USED(o);
  1681  	return -1;
  1682  }
  1683  
  1684  void
  1685  sudoclean(void)
  1686  {
  1687  	return;
  1688  }
  1689  
  1690  /*
  1691   * generate code to compute address of n,
  1692   * a reference to a (perhaps nested) field inside
  1693   * an array or struct.
  1694   * return 0 on failure, 1 on success.
  1695   * on success, leaves usable address in a.
  1696   *
  1697   * caller is responsible for calling sudoclean
  1698   * after successful sudoaddable,
  1699   * to release the register used for a.
  1700   */
  1701  int
  1702  sudoaddable(int as, Node *n, Addr *a)
  1703  {
  1704  	// TODO(minux)
  1705  	USED(as); USED(n); USED(a);
  1706  	return 0;
  1707  }