github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/8g/gsubr.c (about)

     1  // Derived from Inferno utils/8c/txt.c
     2  // http://code.google.com/p/inferno-os/source/browse/utils/8c/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 "../../pkg/runtime/funcdata.h"
    35  
    36  // TODO(rsc): Can make this bigger if we move
    37  // the text segment up higher in 8l for all GOOS.
    38  // At the same time, can raise StackBig in ../../pkg/runtime/stack.h.
    39  uint32 unmappedzero = 4096;
    40  
    41  #define	CASE(a,b)	(((a)<<16)|((b)<<0))
    42  
    43  void
    44  clearp(Prog *p)
    45  {
    46  	p->as = AEND;
    47  	p->from.type = D_NONE;
    48  	p->from.index = D_NONE;
    49  	p->to.type = D_NONE;
    50  	p->to.index = D_NONE;
    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  	} else {
    79  		p = pc;
    80  		pc = mal(sizeof(*pc));
    81  		clearp(pc);
    82  		p->link = pc;
    83  	}
    84  
    85  	if(lineno == 0) {
    86  		if(debug['K'])
    87  			warn("prog: line 0");
    88  	}
    89  
    90  	p->as = as;
    91  	p->lineno = lineno;
    92  	return p;
    93  }
    94  
    95  void
    96  dumpdata(void)
    97  {
    98  	ddumped = 1;
    99  	if(dfirst == nil)
   100  		return;
   101  	newplist();
   102  	*pc = *dfirst;
   103  	pc = dpc;
   104  	clearp(pc);
   105  }
   106  
   107  /*
   108   * generate a branch.
   109   * t is ignored.
   110   * likely values are for branch prediction:
   111   *	-1 unlikely
   112   *	0 no opinion
   113   *	+1 likely
   114   */
   115  Prog*
   116  gbranch(int as, Type *t, int likely)
   117  {
   118  	Prog *p;
   119  
   120  	USED(t);
   121  	p = prog(as);
   122  	p->to.type = D_BRANCH;
   123  	p->to.u.branch = P;
   124  	if(likely != 0) {
   125  		p->from.type = D_CONST;
   126  		p->from.offset = likely > 0;
   127  	}
   128  	return p;
   129  }
   130  
   131  /*
   132   * patch previous branch to jump to to.
   133   */
   134  void
   135  patch(Prog *p, Prog *to)
   136  {
   137  	if(p->to.type != D_BRANCH)
   138  		fatal("patch: not a branch");
   139  	p->to.u.branch = to;
   140  	p->to.offset = to->loc;
   141  }
   142  
   143  Prog*
   144  unpatch(Prog *p)
   145  {
   146  	Prog *q;
   147  
   148  	if(p->to.type != D_BRANCH)
   149  		fatal("unpatch: not a branch");
   150  	q = p->to.u.branch;
   151  	p->to.u.branch = P;
   152  	p->to.offset = 0;
   153  	return q;
   154  }
   155  
   156  /*
   157   * start a new Prog list.
   158   */
   159  Plist*
   160  newplist(void)
   161  {
   162  	Plist *pl;
   163  
   164  	pl = mal(sizeof(*pl));
   165  	if(plist == nil)
   166  		plist = pl;
   167  	else
   168  		plast->link = pl;
   169  	plast = pl;
   170  
   171  	pc = mal(sizeof(*pc));
   172  	clearp(pc);
   173  	pl->firstpc = pc;
   174  
   175  	return pl;
   176  }
   177  
   178  void
   179  gused(Node *n)
   180  {
   181  	gins(ANOP, n, N);	// used
   182  }
   183  
   184  Prog*
   185  gjmp(Prog *to)
   186  {
   187  	Prog *p;
   188  
   189  	p = gbranch(AJMP, T, 0);
   190  	if(to != P)
   191  		patch(p, to);
   192  	return p;
   193  }
   194  
   195  void
   196  ggloblnod(Node *nam)
   197  {
   198  	Prog *p;
   199  
   200  	p = gins(AGLOBL, nam, N);
   201  	p->lineno = nam->lineno;
   202  	p->from.gotype = ngotype(nam);
   203  	p->to.sym = S;
   204  	p->to.type = D_CONST;
   205  	p->to.offset = nam->type->width;
   206  	if(nam->readonly)
   207  		p->from.scale = RODATA;
   208  	if(nam->type != T && !haspointers(nam->type))
   209  		p->from.scale |= NOPTR;
   210  }
   211  
   212  void
   213  gargsize(int32 size)
   214  {
   215  	Node n1, n2;
   216  	
   217  	nodconst(&n1, types[TINT32], PCDATA_ArgSize);
   218  	nodconst(&n2, types[TINT32], size);
   219  	gins(APCDATA, &n1, &n2);
   220  }
   221  
   222  void
   223  ggloblsym(Sym *s, int32 width, int dupok, int rodata)
   224  {
   225  	Prog *p;
   226  
   227  	p = gins(AGLOBL, N, N);
   228  	p->from.type = D_EXTERN;
   229  	p->from.index = D_NONE;
   230  	p->from.sym = s;
   231  	p->to.type = D_CONST;
   232  	p->to.index = D_NONE;
   233  	p->to.offset = width;
   234  	if(dupok)
   235  		p->from.scale |= DUPOK;
   236  	if(rodata)
   237  		p->from.scale |= RODATA;
   238  }
   239  
   240  void
   241  gtrack(Sym *s)
   242  {
   243  	Prog *p;
   244  	
   245  	p = gins(AUSEFIELD, N, N);
   246  	p->from.type = D_EXTERN;
   247  	p->from.index = D_NONE;
   248  	p->from.sym = s;
   249  }
   250  
   251  int
   252  isfat(Type *t)
   253  {
   254  	if(t != T)
   255  	switch(t->etype) {
   256  	case TSTRUCT:
   257  	case TARRAY:
   258  	case TSTRING:
   259  	case TINTER:	// maybe remove later
   260  		return 1;
   261  	}
   262  	return 0;
   263  }
   264  
   265  /*
   266   * naddr of func generates code for address of func.
   267   * if using opcode that can take address implicitly,
   268   * call afunclit to fix up the argument.
   269   */
   270  void
   271  afunclit(Addr *a, Node *n)
   272  {
   273  	if(a->type == D_ADDR && a->index == D_EXTERN) {
   274  		a->type = D_EXTERN;
   275  		a->index = D_NONE;
   276  		a->sym = n->sym;
   277  	}
   278  }
   279  
   280  /*
   281   * return Axxx for Oxxx on type t.
   282   */
   283  int
   284  optoas(int op, Type *t)
   285  {
   286  	int a;
   287  
   288  	if(t == T)
   289  		fatal("optoas: t is nil");
   290  
   291  	a = AGOK;
   292  	switch(CASE(op, simtype[t->etype])) {
   293  	default:
   294  		fatal("optoas: no entry %O-%T", op, t);
   295  		break;
   296  
   297  	case CASE(OADDR, TPTR32):
   298  		a = ALEAL;
   299  		break;
   300  
   301  	case CASE(OEQ, TBOOL):
   302  	case CASE(OEQ, TINT8):
   303  	case CASE(OEQ, TUINT8):
   304  	case CASE(OEQ, TINT16):
   305  	case CASE(OEQ, TUINT16):
   306  	case CASE(OEQ, TINT32):
   307  	case CASE(OEQ, TUINT32):
   308  	case CASE(OEQ, TINT64):
   309  	case CASE(OEQ, TUINT64):
   310  	case CASE(OEQ, TPTR32):
   311  	case CASE(OEQ, TPTR64):
   312  	case CASE(OEQ, TFLOAT32):
   313  	case CASE(OEQ, TFLOAT64):
   314  		a = AJEQ;
   315  		break;
   316  
   317  	case CASE(ONE, TBOOL):
   318  	case CASE(ONE, TINT8):
   319  	case CASE(ONE, TUINT8):
   320  	case CASE(ONE, TINT16):
   321  	case CASE(ONE, TUINT16):
   322  	case CASE(ONE, TINT32):
   323  	case CASE(ONE, TUINT32):
   324  	case CASE(ONE, TINT64):
   325  	case CASE(ONE, TUINT64):
   326  	case CASE(ONE, TPTR32):
   327  	case CASE(ONE, TPTR64):
   328  	case CASE(ONE, TFLOAT32):
   329  	case CASE(ONE, TFLOAT64):
   330  		a = AJNE;
   331  		break;
   332  
   333  	case CASE(OLT, TINT8):
   334  	case CASE(OLT, TINT16):
   335  	case CASE(OLT, TINT32):
   336  	case CASE(OLT, TINT64):
   337  		a = AJLT;
   338  		break;
   339  
   340  	case CASE(OLT, TUINT8):
   341  	case CASE(OLT, TUINT16):
   342  	case CASE(OLT, TUINT32):
   343  	case CASE(OLT, TUINT64):
   344  		a = AJCS;
   345  		break;
   346  
   347  	case CASE(OLE, TINT8):
   348  	case CASE(OLE, TINT16):
   349  	case CASE(OLE, TINT32):
   350  	case CASE(OLE, TINT64):
   351  		a = AJLE;
   352  		break;
   353  
   354  	case CASE(OLE, TUINT8):
   355  	case CASE(OLE, TUINT16):
   356  	case CASE(OLE, TUINT32):
   357  	case CASE(OLE, TUINT64):
   358  		a = AJLS;
   359  		break;
   360  
   361  	case CASE(OGT, TINT8):
   362  	case CASE(OGT, TINT16):
   363  	case CASE(OGT, TINT32):
   364  	case CASE(OGT, TINT64):
   365  		a = AJGT;
   366  		break;
   367  
   368  	case CASE(OGT, TUINT8):
   369  	case CASE(OGT, TUINT16):
   370  	case CASE(OGT, TUINT32):
   371  	case CASE(OGT, TUINT64):
   372  	case CASE(OLT, TFLOAT32):
   373  	case CASE(OLT, TFLOAT64):
   374  		a = AJHI;
   375  		break;
   376  
   377  	case CASE(OGE, TINT8):
   378  	case CASE(OGE, TINT16):
   379  	case CASE(OGE, TINT32):
   380  	case CASE(OGE, TINT64):
   381  		a = AJGE;
   382  		break;
   383  
   384  	case CASE(OGE, TUINT8):
   385  	case CASE(OGE, TUINT16):
   386  	case CASE(OGE, TUINT32):
   387  	case CASE(OGE, TUINT64):
   388  	case CASE(OLE, TFLOAT32):
   389  	case CASE(OLE, TFLOAT64):
   390  		a = AJCC;
   391  		break;
   392  
   393  	case CASE(OCMP, TBOOL):
   394  	case CASE(OCMP, TINT8):
   395  	case CASE(OCMP, TUINT8):
   396  		a = ACMPB;
   397  		break;
   398  
   399  	case CASE(OCMP, TINT16):
   400  	case CASE(OCMP, TUINT16):
   401  		a = ACMPW;
   402  		break;
   403  
   404  	case CASE(OCMP, TINT32):
   405  	case CASE(OCMP, TUINT32):
   406  	case CASE(OCMP, TPTR32):
   407  		a = ACMPL;
   408  		break;
   409  
   410  	case CASE(OAS, TBOOL):
   411  	case CASE(OAS, TINT8):
   412  	case CASE(OAS, TUINT8):
   413  		a = AMOVB;
   414  		break;
   415  
   416  	case CASE(OAS, TINT16):
   417  	case CASE(OAS, TUINT16):
   418  		a = AMOVW;
   419  		break;
   420  
   421  	case CASE(OAS, TINT32):
   422  	case CASE(OAS, TUINT32):
   423  	case CASE(OAS, TPTR32):
   424  		a = AMOVL;
   425  		break;
   426  
   427  	case CASE(OADD, TINT8):
   428  	case CASE(OADD, TUINT8):
   429  		a = AADDB;
   430  		break;
   431  
   432  	case CASE(OADD, TINT16):
   433  	case CASE(OADD, TUINT16):
   434  		a = AADDW;
   435  		break;
   436  
   437  	case CASE(OADD, TINT32):
   438  	case CASE(OADD, TUINT32):
   439  	case CASE(OADD, TPTR32):
   440  		a = AADDL;
   441  		break;
   442  
   443  	case CASE(OSUB, TINT8):
   444  	case CASE(OSUB, TUINT8):
   445  		a = ASUBB;
   446  		break;
   447  
   448  	case CASE(OSUB, TINT16):
   449  	case CASE(OSUB, TUINT16):
   450  		a = ASUBW;
   451  		break;
   452  
   453  	case CASE(OSUB, TINT32):
   454  	case CASE(OSUB, TUINT32):
   455  	case CASE(OSUB, TPTR32):
   456  		a = ASUBL;
   457  		break;
   458  
   459  	case CASE(OINC, TINT8):
   460  	case CASE(OINC, TUINT8):
   461  		a = AINCB;
   462  		break;
   463  
   464  	case CASE(OINC, TINT16):
   465  	case CASE(OINC, TUINT16):
   466  		a = AINCW;
   467  		break;
   468  
   469  	case CASE(OINC, TINT32):
   470  	case CASE(OINC, TUINT32):
   471  	case CASE(OINC, TPTR32):
   472  		a = AINCL;
   473  		break;
   474  
   475  	case CASE(ODEC, TINT8):
   476  	case CASE(ODEC, TUINT8):
   477  		a = ADECB;
   478  		break;
   479  
   480  	case CASE(ODEC, TINT16):
   481  	case CASE(ODEC, TUINT16):
   482  		a = ADECW;
   483  		break;
   484  
   485  	case CASE(ODEC, TINT32):
   486  	case CASE(ODEC, TUINT32):
   487  	case CASE(ODEC, TPTR32):
   488  		a = ADECL;
   489  		break;
   490  
   491  	case CASE(OCOM, TINT8):
   492  	case CASE(OCOM, TUINT8):
   493  		a = ANOTB;
   494  		break;
   495  
   496  	case CASE(OCOM, TINT16):
   497  	case CASE(OCOM, TUINT16):
   498  		a = ANOTW;
   499  		break;
   500  
   501  	case CASE(OCOM, TINT32):
   502  	case CASE(OCOM, TUINT32):
   503  	case CASE(OCOM, TPTR32):
   504  		a = ANOTL;
   505  		break;
   506  
   507  	case CASE(OMINUS, TINT8):
   508  	case CASE(OMINUS, TUINT8):
   509  		a = ANEGB;
   510  		break;
   511  
   512  	case CASE(OMINUS, TINT16):
   513  	case CASE(OMINUS, TUINT16):
   514  		a = ANEGW;
   515  		break;
   516  
   517  	case CASE(OMINUS, TINT32):
   518  	case CASE(OMINUS, TUINT32):
   519  	case CASE(OMINUS, TPTR32):
   520  		a = ANEGL;
   521  		break;
   522  
   523  	case CASE(OAND, TINT8):
   524  	case CASE(OAND, TUINT8):
   525  		a = AANDB;
   526  		break;
   527  
   528  	case CASE(OAND, TINT16):
   529  	case CASE(OAND, TUINT16):
   530  		a = AANDW;
   531  		break;
   532  
   533  	case CASE(OAND, TINT32):
   534  	case CASE(OAND, TUINT32):
   535  	case CASE(OAND, TPTR32):
   536  		a = AANDL;
   537  		break;
   538  
   539  	case CASE(OOR, TINT8):
   540  	case CASE(OOR, TUINT8):
   541  		a = AORB;
   542  		break;
   543  
   544  	case CASE(OOR, TINT16):
   545  	case CASE(OOR, TUINT16):
   546  		a = AORW;
   547  		break;
   548  
   549  	case CASE(OOR, TINT32):
   550  	case CASE(OOR, TUINT32):
   551  	case CASE(OOR, TPTR32):
   552  		a = AORL;
   553  		break;
   554  
   555  	case CASE(OXOR, TINT8):
   556  	case CASE(OXOR, TUINT8):
   557  		a = AXORB;
   558  		break;
   559  
   560  	case CASE(OXOR, TINT16):
   561  	case CASE(OXOR, TUINT16):
   562  		a = AXORW;
   563  		break;
   564  
   565  	case CASE(OXOR, TINT32):
   566  	case CASE(OXOR, TUINT32):
   567  	case CASE(OXOR, TPTR32):
   568  		a = AXORL;
   569  		break;
   570  
   571  	case CASE(OLROT, TINT8):
   572  	case CASE(OLROT, TUINT8):
   573  		a = AROLB;
   574  		break;
   575  
   576  	case CASE(OLROT, TINT16):
   577  	case CASE(OLROT, TUINT16):
   578  		a = AROLW;
   579  		break;
   580  
   581  	case CASE(OLROT, TINT32):
   582  	case CASE(OLROT, TUINT32):
   583  	case CASE(OLROT, TPTR32):
   584  		a = AROLL;
   585  		break;
   586  
   587  	case CASE(OLSH, TINT8):
   588  	case CASE(OLSH, TUINT8):
   589  		a = ASHLB;
   590  		break;
   591  
   592  	case CASE(OLSH, TINT16):
   593  	case CASE(OLSH, TUINT16):
   594  		a = ASHLW;
   595  		break;
   596  
   597  	case CASE(OLSH, TINT32):
   598  	case CASE(OLSH, TUINT32):
   599  	case CASE(OLSH, TPTR32):
   600  		a = ASHLL;
   601  		break;
   602  
   603  	case CASE(ORSH, TUINT8):
   604  		a = ASHRB;
   605  		break;
   606  
   607  	case CASE(ORSH, TUINT16):
   608  		a = ASHRW;
   609  		break;
   610  
   611  	case CASE(ORSH, TUINT32):
   612  	case CASE(ORSH, TPTR32):
   613  		a = ASHRL;
   614  		break;
   615  
   616  	case CASE(ORSH, TINT8):
   617  		a = ASARB;
   618  		break;
   619  
   620  	case CASE(ORSH, TINT16):
   621  		a = ASARW;
   622  		break;
   623  
   624  	case CASE(ORSH, TINT32):
   625  		a = ASARL;
   626  		break;
   627  
   628  	case CASE(OHMUL, TINT8):
   629  	case CASE(OMUL, TINT8):
   630  	case CASE(OMUL, TUINT8):
   631  		a = AIMULB;
   632  		break;
   633  
   634  	case CASE(OHMUL, TINT16):
   635  	case CASE(OMUL, TINT16):
   636  	case CASE(OMUL, TUINT16):
   637  		a = AIMULW;
   638  		break;
   639  
   640  	case CASE(OHMUL, TINT32):
   641  	case CASE(OMUL, TINT32):
   642  	case CASE(OMUL, TUINT32):
   643  	case CASE(OMUL, TPTR32):
   644  		a = AIMULL;
   645  		break;
   646  
   647  	case CASE(OHMUL, TUINT8):
   648  		a = AMULB;
   649  		break;
   650  
   651  	case CASE(OHMUL, TUINT16):
   652  		a = AMULW;
   653  		break;
   654  
   655  	case CASE(OHMUL, TUINT32):
   656  	case CASE(OHMUL, TPTR32):
   657  		a = AMULL;
   658  		break;
   659  
   660  	case CASE(ODIV, TINT8):
   661  	case CASE(OMOD, TINT8):
   662  		a = AIDIVB;
   663  		break;
   664  
   665  	case CASE(ODIV, TUINT8):
   666  	case CASE(OMOD, TUINT8):
   667  		a = ADIVB;
   668  		break;
   669  
   670  	case CASE(ODIV, TINT16):
   671  	case CASE(OMOD, TINT16):
   672  		a = AIDIVW;
   673  		break;
   674  
   675  	case CASE(ODIV, TUINT16):
   676  	case CASE(OMOD, TUINT16):
   677  		a = ADIVW;
   678  		break;
   679  
   680  	case CASE(ODIV, TINT32):
   681  	case CASE(OMOD, TINT32):
   682  		a = AIDIVL;
   683  		break;
   684  
   685  	case CASE(ODIV, TUINT32):
   686  	case CASE(ODIV, TPTR32):
   687  	case CASE(OMOD, TUINT32):
   688  	case CASE(OMOD, TPTR32):
   689  		a = ADIVL;
   690  		break;
   691  
   692  	case CASE(OEXTEND, TINT16):
   693  		a = ACWD;
   694  		break;
   695  
   696  	case CASE(OEXTEND, TINT32):
   697  		a = ACDQ;
   698  		break;
   699  	}
   700  	return a;
   701  }
   702  
   703  #define FCASE(a, b, c)  (((a)<<16)|((b)<<8)|(c))
   704  int
   705  foptoas(int op, Type *t, int flg)
   706  {
   707  	int et, a;
   708  
   709  	a = AGOK;
   710  	et = simtype[t->etype];
   711  
   712  	if(use_sse)
   713  		goto sse;
   714  
   715  	// If we need Fpop, it means we're working on
   716  	// two different floating-point registers, not memory.
   717  	// There the instruction only has a float64 form.
   718  	if(flg & Fpop)
   719  		et = TFLOAT64;
   720  
   721  	// clear Frev if unneeded
   722  	switch(op) {
   723  	case OADD:
   724  	case OMUL:
   725  		flg &= ~Frev;
   726  		break;
   727  	}
   728  
   729  	switch(FCASE(op, et, flg)) {
   730  	case FCASE(OADD, TFLOAT32, 0):
   731  		return AFADDF;
   732  	case FCASE(OADD, TFLOAT64, 0):
   733  		return AFADDD;
   734  	case FCASE(OADD, TFLOAT64, Fpop):
   735  		return AFADDDP;
   736  
   737  	case FCASE(OSUB, TFLOAT32, 0):
   738  		return AFSUBF;
   739  	case FCASE(OSUB, TFLOAT32, Frev):
   740  		return AFSUBRF;
   741  
   742  	case FCASE(OSUB, TFLOAT64, 0):
   743  		return AFSUBD;
   744  	case FCASE(OSUB, TFLOAT64, Frev):
   745  		return AFSUBRD;
   746  	case FCASE(OSUB, TFLOAT64, Fpop):
   747  		return AFSUBDP;
   748  	case FCASE(OSUB, TFLOAT64, Fpop|Frev):
   749  		return AFSUBRDP;
   750  
   751  	case FCASE(OMUL, TFLOAT32, 0):
   752  		return AFMULF;
   753  	case FCASE(OMUL, TFLOAT64, 0):
   754  		return AFMULD;
   755  	case FCASE(OMUL, TFLOAT64, Fpop):
   756  		return AFMULDP;
   757  
   758  	case FCASE(ODIV, TFLOAT32, 0):
   759  		return AFDIVF;
   760  	case FCASE(ODIV, TFLOAT32, Frev):
   761  		return AFDIVRF;
   762  
   763  	case FCASE(ODIV, TFLOAT64, 0):
   764  		return AFDIVD;
   765  	case FCASE(ODIV, TFLOAT64, Frev):
   766  		return AFDIVRD;
   767  	case FCASE(ODIV, TFLOAT64, Fpop):
   768  		return AFDIVDP;
   769  	case FCASE(ODIV, TFLOAT64, Fpop|Frev):
   770  		return AFDIVRDP;
   771  
   772  	case FCASE(OCMP, TFLOAT32, 0):
   773  		return AFCOMF;
   774  	case FCASE(OCMP, TFLOAT32, Fpop):
   775  		return AFCOMFP;
   776  	case FCASE(OCMP, TFLOAT64, 0):
   777  		return AFCOMD;
   778  	case FCASE(OCMP, TFLOAT64, Fpop):
   779  		return AFCOMDP;
   780  	case FCASE(OCMP, TFLOAT64, Fpop2):
   781  		return AFCOMDPP;
   782  	
   783  	case FCASE(OMINUS, TFLOAT32, 0):
   784  		return AFCHS;
   785  	case FCASE(OMINUS, TFLOAT64, 0):
   786  		return AFCHS;
   787  	}
   788  
   789  	fatal("foptoas %O %T %#x", op, t, flg);
   790  	return 0;
   791  
   792  sse:
   793  	switch(CASE(op, et)) {
   794  	default:
   795  		fatal("foptoas-sse: no entry %O-%T", op, t);
   796  		break;
   797  
   798  	case CASE(OCMP, TFLOAT32):
   799  		a = AUCOMISS;
   800  		break;
   801  
   802  	case CASE(OCMP, TFLOAT64):
   803  		a = AUCOMISD;
   804  		break;
   805  
   806  	case CASE(OAS, TFLOAT32):
   807  		a = AMOVSS;
   808  		break;
   809  
   810  	case CASE(OAS, TFLOAT64):
   811  		a = AMOVSD;
   812  		break;
   813  
   814  	case CASE(OADD, TFLOAT32):
   815  		a = AADDSS;
   816  		break;
   817  
   818  	case CASE(OADD, TFLOAT64):
   819  		a = AADDSD;
   820  		break;
   821  
   822  	case CASE(OSUB, TFLOAT32):
   823  		a = ASUBSS;
   824  		break;
   825  
   826  	case CASE(OSUB, TFLOAT64):
   827  		a = ASUBSD;
   828  		break;
   829  
   830  	case CASE(OMUL, TFLOAT32):
   831  		a = AMULSS;
   832  		break;
   833  
   834  	case CASE(OMUL, TFLOAT64):
   835  		a = AMULSD;
   836  		break;
   837  
   838  	case CASE(ODIV, TFLOAT32):
   839  		a = ADIVSS;
   840  		break;
   841  
   842  	case CASE(ODIV, TFLOAT64):
   843  		a = ADIVSD;
   844  		break;
   845  	}
   846  	return a;
   847  }
   848  
   849  
   850  static	int	resvd[] =
   851  {
   852  //	D_DI,	// for movstring
   853  //	D_SI,	// for movstring
   854  
   855  	D_AX,	// for divide
   856  	D_CX,	// for shift
   857  	D_DX,	// for divide
   858  	D_SP,	// for stack
   859  
   860  	D_BL,	// because D_BX can be allocated
   861  	D_BH,
   862  };
   863  
   864  void
   865  ginit(void)
   866  {
   867  	int i;
   868  
   869  	for(i=0; i<nelem(reg); i++)
   870  		reg[i] = 1;
   871  	for(i=D_AX; i<=D_DI; i++)
   872  		reg[i] = 0;
   873  	for(i=D_X0; i<=D_X7; i++)
   874  		reg[i] = 0;
   875  	for(i=0; i<nelem(resvd); i++)
   876  		reg[resvd[i]]++;
   877  }
   878  
   879  uintptr regpc[D_NONE];
   880  
   881  void
   882  gclean(void)
   883  {
   884  	int i;
   885  
   886  	for(i=0; i<nelem(resvd); i++)
   887  		reg[resvd[i]]--;
   888  
   889  	for(i=D_AX; i<=D_DI; i++)
   890  		if(reg[i])
   891  			yyerror("reg %R left allocated at %ux", i, regpc[i]);
   892  	for(i=D_X0; i<=D_X7; i++)
   893  		if(reg[i])
   894  			yyerror("reg %R left allocated\n", i);
   895  }
   896  
   897  int32
   898  anyregalloc(void)
   899  {
   900  	int i, j;
   901  
   902  	for(i=D_AX; i<=D_DI; i++) {
   903  		if(reg[i] == 0)
   904  			goto ok;
   905  		for(j=0; j<nelem(resvd); j++)
   906  			if(resvd[j] == i)
   907  				goto ok;
   908  		return 1;
   909  	ok:;
   910  	}
   911  	for(i=D_X0; i<=D_X7; i++)
   912  		if(reg[i])
   913  			return 1;
   914  	return 0;
   915  }
   916  
   917  /*
   918   * allocate register of type t, leave in n.
   919   * if o != N, o is desired fixed register.
   920   * caller must regfree(n).
   921   */
   922  void
   923  regalloc(Node *n, Type *t, Node *o)
   924  {
   925  	int i, et;
   926  
   927  	if(t == T)
   928  		fatal("regalloc: t nil");
   929  	et = simtype[t->etype];
   930  
   931  	switch(et) {
   932  	case TINT64:
   933  	case TUINT64:
   934  		fatal("regalloc64");
   935  
   936  	case TINT8:
   937  	case TUINT8:
   938  	case TINT16:
   939  	case TUINT16:
   940  	case TINT32:
   941  	case TUINT32:
   942  	case TPTR32:
   943  	case TPTR64:
   944  	case TBOOL:
   945  		if(o != N && o->op == OREGISTER) {
   946  			i = o->val.u.reg;
   947  			if(i >= D_AX && i <= D_DI)
   948  				goto out;
   949  		}
   950  		for(i=D_AX; i<=D_DI; i++)
   951  			if(reg[i] == 0)
   952  				goto out;
   953  
   954  		fprint(2, "registers allocated at\n");
   955  		for(i=D_AX; i<=D_DI; i++)
   956  			fprint(2, "\t%R\t%#lux\n", i, regpc[i]);
   957  		yyerror("out of fixed registers");
   958  		goto err;
   959  
   960  	case TFLOAT32:
   961  	case TFLOAT64:
   962  		if(!use_sse) {
   963  			i = D_F0;
   964  			goto out;
   965  		}
   966  		if(o != N && o->op == OREGISTER) {
   967  			i = o->val.u.reg;
   968  			if(i >= D_X0 && i <= D_X7)
   969  				goto out;
   970  		}
   971  		for(i=D_X0; i<=D_X7; i++)
   972  			if(reg[i] == 0)
   973  				goto out;
   974  		fprint(2, "registers allocated at\n");
   975  		for(i=D_X0; i<=D_X7; i++)
   976  			fprint(2, "\t%R\t%#lux\n", i, regpc[i]);
   977  		fatal("out of floating registers");
   978  	}
   979  	yyerror("regalloc: unknown type %T", t);
   980  
   981  err:
   982  	nodreg(n, t, 0);
   983  	return;
   984  
   985  out:
   986  	if (i == D_SP)
   987  		print("alloc SP\n");
   988  	if(reg[i] == 0) {
   989  		regpc[i] = (uintptr)getcallerpc(&n);
   990  		if(i == D_AX || i == D_CX || i == D_DX || i == D_SP) {
   991  			dump("regalloc-o", o);
   992  			fatal("regalloc %R", i);
   993  		}
   994  	}
   995  	reg[i]++;
   996  	nodreg(n, t, i);
   997  }
   998  
   999  void
  1000  regfree(Node *n)
  1001  {
  1002  	int i;
  1003  	
  1004  	if(n->op == ONAME)
  1005  		return;
  1006  	if(n->op != OREGISTER && n->op != OINDREG)
  1007  		fatal("regfree: not a register");
  1008  	i = n->val.u.reg;
  1009  	if(i == D_SP)
  1010  		return;
  1011  	if(i < 0 || i >= nelem(reg))
  1012  		fatal("regfree: reg out of range");
  1013  	if(reg[i] <= 0)
  1014  		fatal("regfree: reg not allocated");
  1015  	reg[i]--;
  1016  	if(reg[i] == 0 && (i == D_AX || i == D_CX || i == D_DX || i == D_SP))
  1017  		fatal("regfree %R", i);
  1018  }
  1019  
  1020  /*
  1021   * initialize n to be register r of type t.
  1022   */
  1023  void
  1024  nodreg(Node *n, Type *t, int r)
  1025  {
  1026  	if(t == T)
  1027  		fatal("nodreg: t nil");
  1028  
  1029  	memset(n, 0, sizeof(*n));
  1030  	n->op = OREGISTER;
  1031  	n->addable = 1;
  1032  	ullmancalc(n);
  1033  	n->val.u.reg = r;
  1034  	n->type = t;
  1035  }
  1036  
  1037  /*
  1038   * initialize n to be indirect of register r; n is type t.
  1039   */
  1040  void
  1041  nodindreg(Node *n, Type *t, int r)
  1042  {
  1043  	nodreg(n, t, r);
  1044  	n->op = OINDREG;
  1045  }
  1046  
  1047  Node*
  1048  nodarg(Type *t, int fp)
  1049  {
  1050  	Node *n;
  1051  	Type *first;
  1052  	Iter savet;
  1053  
  1054  	// entire argument struct, not just one arg
  1055  	switch(t->etype) {
  1056  	default:
  1057  		fatal("nodarg %T", t);
  1058  
  1059  	case TSTRUCT:
  1060  		if(!t->funarg)
  1061  			fatal("nodarg: TSTRUCT but not funarg");
  1062  		n = nod(ONAME, N, N);
  1063  		n->sym = lookup(".args");
  1064  		n->type = t;
  1065  		first = structfirst(&savet, &t);
  1066  		if(first == nil)
  1067  			fatal("nodarg: bad struct");
  1068  		if(first->width == BADWIDTH)
  1069  			fatal("nodarg: offset not computed for %T", t);
  1070  		n->xoffset = first->width;
  1071  		n->addable = 1;
  1072  		break;
  1073  
  1074  	case TFIELD:
  1075  		n = nod(ONAME, N, N);
  1076  		n->type = t->type;
  1077  		n->sym = t->sym;
  1078  		if(t->width == BADWIDTH)
  1079  			fatal("nodarg: offset not computed for %T", t);
  1080  		n->xoffset = t->width;
  1081  		n->addable = 1;
  1082  		n->orig = t->nname;
  1083  		break;
  1084  	}
  1085  	
  1086  	// Rewrite argument named _ to __,
  1087  	// or else the assignment to _ will be
  1088  	// discarded during code generation.
  1089  	if(isblank(n))
  1090  		n->sym = lookup("__");
  1091  
  1092  	switch(fp) {
  1093  	default:
  1094  		fatal("nodarg %T %d", t, fp);
  1095  
  1096  	case 0:		// output arg
  1097  		n->op = OINDREG;
  1098  		n->val.u.reg = D_SP;
  1099  		break;
  1100  
  1101  	case 1:		// input arg
  1102  		n->class = PPARAM;
  1103  		break;
  1104  	}
  1105  
  1106  	n->typecheck = 1;
  1107  	return n;
  1108  }
  1109  
  1110  /*
  1111   * generate
  1112   *	as $c, reg
  1113   */
  1114  void
  1115  gconreg(int as, vlong c, int reg)
  1116  {
  1117  	Node n1, n2;
  1118  
  1119  	nodconst(&n1, types[TINT64], c);
  1120  	nodreg(&n2, types[TINT64], reg);
  1121  	gins(as, &n1, &n2);
  1122  }
  1123  
  1124  /*
  1125   * swap node contents
  1126   */
  1127  void
  1128  nswap(Node *a, Node *b)
  1129  {
  1130  	Node t;
  1131  
  1132  	t = *a;
  1133  	*a = *b;
  1134  	*b = t;
  1135  }
  1136  
  1137  /*
  1138   * return constant i node.
  1139   * overwritten by next call, but useful in calls to gins.
  1140   */
  1141  Node*
  1142  ncon(uint32 i)
  1143  {
  1144  	static Node n;
  1145  
  1146  	if(n.type == T)
  1147  		nodconst(&n, types[TUINT32], 0);
  1148  	mpmovecfix(n.val.u.xval, i);
  1149  	return &n;
  1150  }
  1151  
  1152  /*
  1153   * Is this node a memory operand?
  1154   */
  1155  int
  1156  ismem(Node *n)
  1157  {
  1158  	switch(n->op) {
  1159  	case OITAB:
  1160  	case OSPTR:
  1161  	case OLEN:
  1162  	case OCAP:
  1163  	case OINDREG:
  1164  	case ONAME:
  1165  	case OPARAM:
  1166  	case OCLOSUREVAR:
  1167  		return 1;
  1168  	}
  1169  	return 0;
  1170  }
  1171  
  1172  Node sclean[10];
  1173  int nsclean;
  1174  
  1175  /*
  1176   * n is a 64-bit value.  fill in lo and hi to refer to its 32-bit halves.
  1177   */
  1178  void
  1179  split64(Node *n, Node *lo, Node *hi)
  1180  {
  1181  	Node n1;
  1182  	int64 i;
  1183  
  1184  	if(!is64(n->type))
  1185  		fatal("split64 %T", n->type);
  1186  
  1187  	if(nsclean >= nelem(sclean))
  1188  		fatal("split64 clean");
  1189  	sclean[nsclean].op = OEMPTY;
  1190  	nsclean++;
  1191  	switch(n->op) {
  1192  	default:
  1193  		if(!dotaddable(n, &n1)) {
  1194  			igen(n, &n1, N);
  1195  			sclean[nsclean-1] = n1;
  1196  		}
  1197  		n = &n1;
  1198  		goto common;
  1199  	case ONAME:
  1200  		if(n->class == PPARAMREF) {
  1201  			cgen(n->heapaddr, &n1);
  1202  			sclean[nsclean-1] = n1;
  1203  			// fall through.
  1204  			n = &n1;
  1205  		}
  1206  		goto common;
  1207  	case OINDREG:
  1208  	common:
  1209  		*lo = *n;
  1210  		*hi = *n;
  1211  		lo->type = types[TUINT32];
  1212  		if(n->type->etype == TINT64)
  1213  			hi->type = types[TINT32];
  1214  		else
  1215  			hi->type = types[TUINT32];
  1216  		hi->xoffset += 4;
  1217  		break;
  1218  
  1219  	case OLITERAL:
  1220  		convconst(&n1, n->type, &n->val);
  1221  		i = mpgetfix(n1.val.u.xval);
  1222  		nodconst(lo, types[TUINT32], (uint32)i);
  1223  		i >>= 32;
  1224  		if(n->type->etype == TINT64)
  1225  			nodconst(hi, types[TINT32], (int32)i);
  1226  		else
  1227  			nodconst(hi, types[TUINT32], (uint32)i);
  1228  		break;
  1229  	}
  1230  }
  1231  
  1232  void
  1233  splitclean(void)
  1234  {
  1235  	if(nsclean <= 0)
  1236  		fatal("splitclean");
  1237  	nsclean--;
  1238  	if(sclean[nsclean].op != OEMPTY)
  1239  		regfree(&sclean[nsclean]);
  1240  }
  1241  
  1242  /*
  1243   * set up nodes representing fp constants
  1244   */
  1245  Node zerof;
  1246  Node two64f;
  1247  Node two63f;
  1248  
  1249  void
  1250  bignodes(void)
  1251  {
  1252  	static int did;
  1253  
  1254  	if(did)
  1255  		return;
  1256  	did = 1;
  1257  
  1258  	two64f = *ncon(0);
  1259  	two64f.type = types[TFLOAT64];
  1260  	two64f.val.ctype = CTFLT;
  1261  	two64f.val.u.fval = mal(sizeof *two64f.val.u.fval);
  1262  	mpmovecflt(two64f.val.u.fval, 18446744073709551616.);
  1263  
  1264  	two63f = two64f;
  1265  	two63f.val.u.fval = mal(sizeof *two63f.val.u.fval);
  1266  	mpmovecflt(two63f.val.u.fval, 9223372036854775808.);
  1267  
  1268  	zerof = two64f;
  1269  	zerof.val.u.fval = mal(sizeof *zerof.val.u.fval);
  1270  	mpmovecflt(zerof.val.u.fval, 0);
  1271  }
  1272  
  1273  void
  1274  memname(Node *n, Type *t)
  1275  {
  1276  	tempname(n, t);
  1277  	strcpy(namebuf, n->sym->name);
  1278  	namebuf[0] = '.';	// keep optimizer from registerizing
  1279  	n->sym = lookup(namebuf);
  1280  	n->orig->sym = n->sym;
  1281  }
  1282  
  1283  static void floatmove(Node *f, Node *t);
  1284  static void floatmove_387(Node *f, Node *t);
  1285  static void floatmove_sse(Node *f, Node *t);
  1286  
  1287  void
  1288  gmove(Node *f, Node *t)
  1289  {
  1290  	int a, ft, tt;
  1291  	Type *cvt;
  1292  	Node r1, r2, flo, fhi, tlo, thi, con;
  1293  
  1294  	if(debug['M'])
  1295  		print("gmove %N -> %N\n", f, t);
  1296  
  1297  	ft = simsimtype(f->type);
  1298  	tt = simsimtype(t->type);
  1299  	cvt = t->type;
  1300  	
  1301  	if(iscomplex[ft] || iscomplex[tt]) {
  1302  		complexmove(f, t);
  1303  		return;
  1304  	}
  1305  	if(isfloat[ft] || isfloat[tt]) {
  1306  		floatmove(f, t);
  1307  		return;
  1308  	}
  1309  
  1310  	// cannot have two integer memory operands;
  1311  	// except 64-bit, which always copies via registers anyway.
  1312  	if(isint[ft] && isint[tt] && !is64(f->type) && !is64(t->type) && ismem(f) && ismem(t))
  1313  		goto hard;
  1314  
  1315  	// convert constant to desired type
  1316  	if(f->op == OLITERAL) {
  1317  		convconst(&con, t->type, &f->val);
  1318  		f = &con;
  1319  		ft = simsimtype(con.type);
  1320  	}
  1321  
  1322  	// value -> value copy, only one memory operand.
  1323  	// figure out the instruction to use.
  1324  	// break out of switch for one-instruction gins.
  1325  	// goto rdst for "destination must be register".
  1326  	// goto hard for "convert to cvt type first".
  1327  	// otherwise handle and return.
  1328  
  1329  	switch(CASE(ft, tt)) {
  1330  	default:
  1331  		goto fatal;
  1332  
  1333  	/*
  1334  	 * integer copy and truncate
  1335  	 */
  1336  	case CASE(TINT8, TINT8):	// same size
  1337  	case CASE(TINT8, TUINT8):
  1338  	case CASE(TUINT8, TINT8):
  1339  	case CASE(TUINT8, TUINT8):
  1340  		a = AMOVB;
  1341  		break;
  1342  
  1343  	case CASE(TINT16, TINT8):	// truncate
  1344  	case CASE(TUINT16, TINT8):
  1345  	case CASE(TINT32, TINT8):
  1346  	case CASE(TUINT32, TINT8):
  1347  	case CASE(TINT16, TUINT8):
  1348  	case CASE(TUINT16, TUINT8):
  1349  	case CASE(TINT32, TUINT8):
  1350  	case CASE(TUINT32, TUINT8):
  1351  		a = AMOVB;
  1352  		goto rsrc;
  1353  
  1354  	case CASE(TINT64, TINT8):	// truncate low word
  1355  	case CASE(TUINT64, TINT8):
  1356  	case CASE(TINT64, TUINT8):
  1357  	case CASE(TUINT64, TUINT8):
  1358  		split64(f, &flo, &fhi);
  1359  		nodreg(&r1, t->type, D_AX);
  1360  		gmove(&flo, &r1);
  1361  		gins(AMOVB, &r1, t);
  1362  		splitclean();
  1363  		return;
  1364  
  1365  	case CASE(TINT16, TINT16):	// same size
  1366  	case CASE(TINT16, TUINT16):
  1367  	case CASE(TUINT16, TINT16):
  1368  	case CASE(TUINT16, TUINT16):
  1369  		a = AMOVW;
  1370  		break;
  1371  
  1372  	case CASE(TINT32, TINT16):	// truncate
  1373  	case CASE(TUINT32, TINT16):
  1374  	case CASE(TINT32, TUINT16):
  1375  	case CASE(TUINT32, TUINT16):
  1376  		a = AMOVW;
  1377  		goto rsrc;
  1378  
  1379  	case CASE(TINT64, TINT16):	// truncate low word
  1380  	case CASE(TUINT64, TINT16):
  1381  	case CASE(TINT64, TUINT16):
  1382  	case CASE(TUINT64, TUINT16):
  1383  		split64(f, &flo, &fhi);
  1384  		nodreg(&r1, t->type, D_AX);
  1385  		gmove(&flo, &r1);
  1386  		gins(AMOVW, &r1, t);
  1387  		splitclean();
  1388  		return;
  1389  
  1390  	case CASE(TINT32, TINT32):	// same size
  1391  	case CASE(TINT32, TUINT32):
  1392  	case CASE(TUINT32, TINT32):
  1393  	case CASE(TUINT32, TUINT32):
  1394  		a = AMOVL;
  1395  		break;
  1396  
  1397  	case CASE(TINT64, TINT32):	// truncate
  1398  	case CASE(TUINT64, TINT32):
  1399  	case CASE(TINT64, TUINT32):
  1400  	case CASE(TUINT64, TUINT32):
  1401  		split64(f, &flo, &fhi);
  1402  		nodreg(&r1, t->type, D_AX);
  1403  		gmove(&flo, &r1);
  1404  		gins(AMOVL, &r1, t);
  1405  		splitclean();
  1406  		return;
  1407  
  1408  	case CASE(TINT64, TINT64):	// same size
  1409  	case CASE(TINT64, TUINT64):
  1410  	case CASE(TUINT64, TINT64):
  1411  	case CASE(TUINT64, TUINT64):
  1412  		split64(f, &flo, &fhi);
  1413  		split64(t, &tlo, &thi);
  1414  		if(f->op == OLITERAL) {
  1415  			gins(AMOVL, &flo, &tlo);
  1416  			gins(AMOVL, &fhi, &thi);
  1417  		} else {
  1418  			nodreg(&r1, t->type, D_AX);
  1419  			nodreg(&r2, t->type, D_DX);
  1420  			gins(AMOVL, &flo, &r1);
  1421  			gins(AMOVL, &fhi, &r2);
  1422  			gins(AMOVL, &r1, &tlo);
  1423  			gins(AMOVL, &r2, &thi);
  1424  		}
  1425  		splitclean();
  1426  		splitclean();
  1427  		return;
  1428  
  1429  	/*
  1430  	 * integer up-conversions
  1431  	 */
  1432  	case CASE(TINT8, TINT16):	// sign extend int8
  1433  	case CASE(TINT8, TUINT16):
  1434  		a = AMOVBWSX;
  1435  		goto rdst;
  1436  	case CASE(TINT8, TINT32):
  1437  	case CASE(TINT8, TUINT32):
  1438  		a = AMOVBLSX;
  1439  		goto rdst;
  1440  	case CASE(TINT8, TINT64):	// convert via int32
  1441  	case CASE(TINT8, TUINT64):
  1442  		cvt = types[TINT32];
  1443  		goto hard;
  1444  
  1445  	case CASE(TUINT8, TINT16):	// zero extend uint8
  1446  	case CASE(TUINT8, TUINT16):
  1447  		a = AMOVBWZX;
  1448  		goto rdst;
  1449  	case CASE(TUINT8, TINT32):
  1450  	case CASE(TUINT8, TUINT32):
  1451  		a = AMOVBLZX;
  1452  		goto rdst;
  1453  	case CASE(TUINT8, TINT64):	// convert via uint32
  1454  	case CASE(TUINT8, TUINT64):
  1455  		cvt = types[TUINT32];
  1456  		goto hard;
  1457  
  1458  	case CASE(TINT16, TINT32):	// sign extend int16
  1459  	case CASE(TINT16, TUINT32):
  1460  		a = AMOVWLSX;
  1461  		goto rdst;
  1462  	case CASE(TINT16, TINT64):	// convert via int32
  1463  	case CASE(TINT16, TUINT64):
  1464  		cvt = types[TINT32];
  1465  		goto hard;
  1466  
  1467  	case CASE(TUINT16, TINT32):	// zero extend uint16
  1468  	case CASE(TUINT16, TUINT32):
  1469  		a = AMOVWLZX;
  1470  		goto rdst;
  1471  	case CASE(TUINT16, TINT64):	// convert via uint32
  1472  	case CASE(TUINT16, TUINT64):
  1473  		cvt = types[TUINT32];
  1474  		goto hard;
  1475  
  1476  	case CASE(TINT32, TINT64):	// sign extend int32
  1477  	case CASE(TINT32, TUINT64):
  1478  		split64(t, &tlo, &thi);
  1479  		nodreg(&flo, tlo.type, D_AX);
  1480  		nodreg(&fhi, thi.type, D_DX);
  1481  		gmove(f, &flo);
  1482  		gins(ACDQ, N, N);
  1483  		gins(AMOVL, &flo, &tlo);
  1484  		gins(AMOVL, &fhi, &thi);
  1485  		splitclean();
  1486  		return;
  1487  
  1488  	case CASE(TUINT32, TINT64):	// zero extend uint32
  1489  	case CASE(TUINT32, TUINT64):
  1490  		split64(t, &tlo, &thi);
  1491  		gmove(f, &tlo);
  1492  		gins(AMOVL, ncon(0), &thi);
  1493  		splitclean();
  1494  		return;
  1495  	}
  1496  
  1497  	gins(a, f, t);
  1498  	return;
  1499  
  1500  rsrc:
  1501  	// requires register source
  1502  	regalloc(&r1, f->type, t);
  1503  	gmove(f, &r1);
  1504  	gins(a, &r1, t);
  1505  	regfree(&r1);
  1506  	return;
  1507  
  1508  rdst:
  1509  	// requires register destination
  1510  	regalloc(&r1, t->type, t);
  1511  	gins(a, f, &r1);
  1512  	gmove(&r1, t);
  1513  	regfree(&r1);
  1514  	return;
  1515  
  1516  hard:
  1517  	// requires register intermediate
  1518  	regalloc(&r1, cvt, t);
  1519  	gmove(f, &r1);
  1520  	gmove(&r1, t);
  1521  	regfree(&r1);
  1522  	return;
  1523  
  1524  fatal:
  1525  	// should not happen
  1526  	fatal("gmove %N -> %N", f, t);
  1527  }
  1528  
  1529  static void
  1530  floatmove(Node *f, Node *t)
  1531  {
  1532  	Node r1, r2, t1, t2, tlo, thi, con, f0, f1, ax, dx, cx;
  1533  	Type *cvt;
  1534  	int ft, tt;
  1535  	Prog *p1, *p2, *p3;
  1536  
  1537  	ft = simsimtype(f->type);
  1538  	tt = simsimtype(t->type);
  1539  	cvt = t->type;
  1540  
  1541  	// cannot have two floating point memory operands.
  1542  	if(isfloat[ft] && isfloat[tt] && ismem(f) && ismem(t))
  1543  		goto hard;
  1544  
  1545  	// convert constant to desired type
  1546  	if(f->op == OLITERAL) {
  1547  		convconst(&con, t->type, &f->val);
  1548  		f = &con;
  1549  		ft = simsimtype(con.type);
  1550  
  1551  		// some constants can't move directly to memory.
  1552  		if(ismem(t)) {
  1553  			// float constants come from memory.
  1554  			if(isfloat[tt])
  1555  				goto hard;
  1556  		}
  1557  	}
  1558  
  1559  	// value -> value copy, only one memory operand.
  1560  	// figure out the instruction to use.
  1561  	// break out of switch for one-instruction gins.
  1562  	// goto rdst for "destination must be register".
  1563  	// goto hard for "convert to cvt type first".
  1564  	// otherwise handle and return.
  1565  
  1566  	switch(CASE(ft, tt)) {
  1567  	default:
  1568  		if(use_sse)
  1569  			floatmove_sse(f, t);
  1570  		else
  1571  			floatmove_387(f, t);
  1572  		return;
  1573  
  1574  	// float to very long integer.
  1575  	case CASE(TFLOAT32, TINT64):
  1576  	case CASE(TFLOAT64, TINT64):
  1577  		if(f->op == OREGISTER) {
  1578  			cvt = f->type;
  1579  			goto hardmem;
  1580  		}
  1581  		nodreg(&r1, types[ft], D_F0);
  1582  		if(ft == TFLOAT32)
  1583  			gins(AFMOVF, f, &r1);
  1584  		else
  1585  			gins(AFMOVD, f, &r1);
  1586  
  1587  		// set round to zero mode during conversion
  1588  		memname(&t1, types[TUINT16]);
  1589  		memname(&t2, types[TUINT16]);
  1590  		gins(AFSTCW, N, &t1);
  1591  		gins(AMOVW, ncon(0xf7f), &t2);
  1592  		gins(AFLDCW, &t2, N);
  1593  		if(tt == TINT16)
  1594  			gins(AFMOVWP, &r1, t);
  1595  		else if(tt == TINT32)
  1596  			gins(AFMOVLP, &r1, t);
  1597  		else
  1598  			gins(AFMOVVP, &r1, t);
  1599  		gins(AFLDCW, &t1, N);
  1600  		return;
  1601  
  1602  	case CASE(TFLOAT32, TUINT64):
  1603  	case CASE(TFLOAT64, TUINT64):
  1604  		if(!ismem(f)) {
  1605  			cvt = f->type;
  1606  			goto hardmem;
  1607  		}
  1608  		bignodes();
  1609  		nodreg(&f0, types[ft], D_F0);
  1610  		nodreg(&f1, types[ft], D_F0 + 1);
  1611  		nodreg(&ax, types[TUINT16], D_AX);
  1612  
  1613  		if(ft == TFLOAT32)
  1614  			gins(AFMOVF, f, &f0);
  1615  		else
  1616  			gins(AFMOVD, f, &f0);
  1617  
  1618  		// if 0 > v { answer = 0 }
  1619  		gins(AFMOVD, &zerof, &f0);
  1620  		gins(AFUCOMIP, &f0, &f1);
  1621  		p1 = gbranch(optoas(OGT, types[tt]), T, 0);
  1622  		// if 1<<64 <= v { answer = 0 too }
  1623  		gins(AFMOVD, &two64f, &f0);
  1624  		gins(AFUCOMIP, &f0, &f1);
  1625  		p2 = gbranch(optoas(OGT, types[tt]), T, 0);
  1626  		patch(p1, pc);
  1627  		gins(AFMOVVP, &f0, t);	// don't care about t, but will pop the stack
  1628  		split64(t, &tlo, &thi);
  1629  		gins(AMOVL, ncon(0), &tlo);
  1630  		gins(AMOVL, ncon(0), &thi);
  1631  		splitclean();
  1632  		p1 = gbranch(AJMP, T, 0);
  1633  		patch(p2, pc);
  1634  
  1635  		// in range; algorithm is:
  1636  		//	if small enough, use native float64 -> int64 conversion.
  1637  		//	otherwise, subtract 2^63, convert, and add it back.
  1638  
  1639  		// set round to zero mode during conversion
  1640  		memname(&t1, types[TUINT16]);
  1641  		memname(&t2, types[TUINT16]);
  1642  		gins(AFSTCW, N, &t1);
  1643  		gins(AMOVW, ncon(0xf7f), &t2);
  1644  		gins(AFLDCW, &t2, N);
  1645  
  1646  		// actual work
  1647  		gins(AFMOVD, &two63f, &f0);
  1648  		gins(AFUCOMIP, &f0, &f1);
  1649  		p2 = gbranch(optoas(OLE, types[tt]), T, 0);
  1650  		gins(AFMOVVP, &f0, t);
  1651  		p3 = gbranch(AJMP, T, 0);
  1652  		patch(p2, pc);
  1653  		gins(AFMOVD, &two63f, &f0);
  1654  		gins(AFSUBDP, &f0, &f1);
  1655  		gins(AFMOVVP, &f0, t);
  1656  		split64(t, &tlo, &thi);
  1657  		gins(AXORL, ncon(0x80000000), &thi);	// + 2^63
  1658  		patch(p3, pc);
  1659  		splitclean();
  1660  		// restore rounding mode
  1661  		gins(AFLDCW, &t1, N);
  1662  
  1663  		patch(p1, pc);
  1664  		return;
  1665  
  1666  	/*
  1667  	 * integer to float
  1668  	 */
  1669  	case CASE(TINT64, TFLOAT32):
  1670  	case CASE(TINT64, TFLOAT64):
  1671  		if(t->op == OREGISTER)
  1672  			goto hardmem;
  1673  		nodreg(&f0, t->type, D_F0);
  1674  		gins(AFMOVV, f, &f0);
  1675  		if(tt == TFLOAT32)
  1676  			gins(AFMOVFP, &f0, t);
  1677  		else
  1678  			gins(AFMOVDP, &f0, t);
  1679  		return;
  1680  
  1681  	case CASE(TUINT64, TFLOAT32):
  1682  	case CASE(TUINT64, TFLOAT64):
  1683  		// algorithm is:
  1684  		//	if small enough, use native int64 -> float64 conversion.
  1685  		//	otherwise, halve (rounding to odd?), convert, and double.
  1686  		nodreg(&ax, types[TUINT32], D_AX);
  1687  		nodreg(&dx, types[TUINT32], D_DX);
  1688  		nodreg(&cx, types[TUINT32], D_CX);
  1689  		tempname(&t1, f->type);
  1690  		split64(&t1, &tlo, &thi);
  1691  		gmove(f, &t1);
  1692  		gins(ACMPL, &thi, ncon(0));
  1693  		p1 = gbranch(AJLT, T, 0);
  1694  		// native
  1695  		t1.type = types[TINT64];
  1696  		nodreg(&r1, types[tt], D_F0);
  1697  		gins(AFMOVV, &t1, &r1);
  1698  		if(tt == TFLOAT32)
  1699  			gins(AFMOVFP, &r1, t);
  1700  		else
  1701  			gins(AFMOVDP, &r1, t);
  1702  		p2 = gbranch(AJMP, T, 0);
  1703  		// simulated
  1704  		patch(p1, pc);
  1705  		gmove(&tlo, &ax);
  1706  		gmove(&thi, &dx);
  1707  		p1 = gins(ASHRL, ncon(1), &ax);
  1708  		p1->from.index = D_DX;	// double-width shift DX -> AX
  1709  		p1->from.scale = 0;
  1710  		gins(AMOVL, ncon(0), &cx);
  1711  		gins(ASETCC, N, &cx);
  1712  		gins(AORL, &cx, &ax);
  1713  		gins(ASHRL, ncon(1), &dx);
  1714  		gmove(&dx, &thi);
  1715  		gmove(&ax, &tlo);
  1716  		nodreg(&r1, types[tt], D_F0);
  1717  		nodreg(&r2, types[tt], D_F0 + 1);
  1718  		gins(AFMOVV, &t1, &r1);
  1719  		gins(AFMOVD, &r1, &r1);
  1720  		gins(AFADDDP, &r1, &r2);
  1721  		if(tt == TFLOAT32)
  1722  			gins(AFMOVFP, &r1, t);
  1723  		else
  1724  			gins(AFMOVDP, &r1, t);
  1725  		patch(p2, pc);
  1726  		splitclean();
  1727  		return;
  1728  	}
  1729  
  1730  hard:
  1731  	// requires register intermediate
  1732  	regalloc(&r1, cvt, t);
  1733  	gmove(f, &r1);
  1734  	gmove(&r1, t);
  1735  	regfree(&r1);
  1736  	return;
  1737  
  1738  hardmem:
  1739  	// requires memory intermediate
  1740  	tempname(&r1, cvt);
  1741  	gmove(f, &r1);
  1742  	gmove(&r1, t);
  1743  	return;
  1744  }
  1745  
  1746  static void
  1747  floatmove_387(Node *f, Node *t)
  1748  {
  1749  	Node r1, t1, t2;
  1750  	Type *cvt;
  1751  	Prog *p1, *p2, *p3;
  1752  	int a, ft, tt;
  1753  
  1754  	ft = simsimtype(f->type);
  1755  	tt = simsimtype(t->type);
  1756  	cvt = t->type;
  1757  
  1758  	switch(CASE(ft, tt)) {
  1759  	default:
  1760  		goto fatal;
  1761  
  1762  	/*
  1763  	* float to integer
  1764  	*/
  1765  	case CASE(TFLOAT32, TINT16):
  1766  	case CASE(TFLOAT32, TINT32):
  1767  	case CASE(TFLOAT32, TINT64):
  1768  	case CASE(TFLOAT64, TINT16):
  1769  	case CASE(TFLOAT64, TINT32):
  1770  	case CASE(TFLOAT64, TINT64):
  1771  		if(t->op == OREGISTER)
  1772  			goto hardmem;
  1773  		nodreg(&r1, types[ft], D_F0);
  1774  		if(f->op != OREGISTER) {
  1775  			if(ft == TFLOAT32)
  1776  				gins(AFMOVF, f, &r1);
  1777  			else
  1778  				gins(AFMOVD, f, &r1);
  1779  		}
  1780  
  1781  		// set round to zero mode during conversion
  1782  		memname(&t1, types[TUINT16]);
  1783  		memname(&t2, types[TUINT16]);
  1784  		gins(AFSTCW, N, &t1);
  1785  		gins(AMOVW, ncon(0xf7f), &t2);
  1786  		gins(AFLDCW, &t2, N);
  1787  		if(tt == TINT16)
  1788  			gins(AFMOVWP, &r1, t);
  1789  		else if(tt == TINT32)
  1790  			gins(AFMOVLP, &r1, t);
  1791  		else
  1792  			gins(AFMOVVP, &r1, t);
  1793  		gins(AFLDCW, &t1, N);
  1794  		return;
  1795  
  1796  	case CASE(TFLOAT32, TINT8):
  1797  	case CASE(TFLOAT32, TUINT16):
  1798  	case CASE(TFLOAT32, TUINT8):
  1799  	case CASE(TFLOAT64, TINT8):
  1800  	case CASE(TFLOAT64, TUINT16):
  1801  	case CASE(TFLOAT64, TUINT8):
  1802  		// convert via int32.
  1803  		tempname(&t1, types[TINT32]);
  1804  		gmove(f, &t1);
  1805  		switch(tt) {
  1806  		default:
  1807  			fatal("gmove %T", t);
  1808  		case TINT8:
  1809  			gins(ACMPL, &t1, ncon(-0x80));
  1810  			p1 = gbranch(optoas(OLT, types[TINT32]), T, -1);
  1811  			gins(ACMPL, &t1, ncon(0x7f));
  1812  			p2 = gbranch(optoas(OGT, types[TINT32]), T, -1);
  1813  			p3 = gbranch(AJMP, T, 0);
  1814  			patch(p1, pc);
  1815  			patch(p2, pc);
  1816  			gmove(ncon(-0x80), &t1);
  1817  			patch(p3, pc);
  1818  			gmove(&t1, t);
  1819  			break;
  1820  		case TUINT8:
  1821  			gins(ATESTL, ncon(0xffffff00), &t1);
  1822  			p1 = gbranch(AJEQ, T, +1);
  1823  			gins(AMOVL, ncon(0), &t1);
  1824  			patch(p1, pc);
  1825  			gmove(&t1, t);
  1826  			break;
  1827  		case TUINT16:
  1828  			gins(ATESTL, ncon(0xffff0000), &t1);
  1829  			p1 = gbranch(AJEQ, T, +1);
  1830  			gins(AMOVL, ncon(0), &t1);
  1831  			patch(p1, pc);
  1832  			gmove(&t1, t);
  1833  			break;
  1834  		}
  1835  		return;
  1836  
  1837  	case CASE(TFLOAT32, TUINT32):
  1838  	case CASE(TFLOAT64, TUINT32):
  1839  		// convert via int64.
  1840  		cvt = types[TINT64];
  1841  		goto hardmem;
  1842  
  1843  	/*
  1844  	 * integer to float
  1845  	 */
  1846  	case CASE(TINT16, TFLOAT32):
  1847  	case CASE(TINT16, TFLOAT64):
  1848  	case CASE(TINT32, TFLOAT32):
  1849  	case CASE(TINT32, TFLOAT64):
  1850  	case CASE(TINT64, TFLOAT32):
  1851  	case CASE(TINT64, TFLOAT64):
  1852  		if(t->op != OREGISTER)
  1853  			goto hard;
  1854  		if(f->op == OREGISTER) {
  1855  			cvt = f->type;
  1856  			goto hardmem;
  1857  		}
  1858  		switch(ft) {
  1859  		case TINT16:
  1860  			a = AFMOVW;
  1861  			break;
  1862  		case TINT32:
  1863  			a = AFMOVL;
  1864  			break;
  1865  		default:
  1866  			a = AFMOVV;
  1867  			break;
  1868  		}
  1869  		break;
  1870  
  1871  	case CASE(TINT8, TFLOAT32):
  1872  	case CASE(TINT8, TFLOAT64):
  1873  	case CASE(TUINT16, TFLOAT32):
  1874  	case CASE(TUINT16, TFLOAT64):
  1875  	case CASE(TUINT8, TFLOAT32):
  1876  	case CASE(TUINT8, TFLOAT64):
  1877  		// convert via int32 memory
  1878  		cvt = types[TINT32];
  1879  		goto hardmem;
  1880  
  1881  	case CASE(TUINT32, TFLOAT32):
  1882  	case CASE(TUINT32, TFLOAT64):
  1883  		// convert via int64 memory
  1884  		cvt = types[TINT64];
  1885  		goto hardmem;
  1886  
  1887  	/*
  1888  	 * float to float
  1889  	 */
  1890  	case CASE(TFLOAT32, TFLOAT32):
  1891  	case CASE(TFLOAT64, TFLOAT64):
  1892  		// The way the code generator uses floating-point
  1893  		// registers, a move from F0 to F0 is intended as a no-op.
  1894  		// On the x86, it's not: it pushes a second copy of F0
  1895  		// on the floating point stack.  So toss it away here.
  1896  		// Also, F0 is the *only* register we ever evaluate
  1897  		// into, so we should only see register/register as F0/F0.
  1898  		if(ismem(f) && ismem(t))
  1899  			goto hard;
  1900  		if(f->op == OREGISTER && t->op == OREGISTER) {
  1901  			if(f->val.u.reg != D_F0 || t->val.u.reg != D_F0)
  1902  				goto fatal;
  1903  			return;
  1904  		}
  1905  		a = AFMOVF;
  1906  		if(ft == TFLOAT64)
  1907  			a = AFMOVD;
  1908  		if(ismem(t)) {
  1909  			if(f->op != OREGISTER || f->val.u.reg != D_F0)
  1910  				fatal("gmove %N", f);
  1911  			a = AFMOVFP;
  1912  			if(ft == TFLOAT64)
  1913  				a = AFMOVDP;
  1914  		}
  1915  		break;
  1916  
  1917  	case CASE(TFLOAT32, TFLOAT64):
  1918  		if(ismem(f) && ismem(t))
  1919  			goto hard;
  1920  		if(f->op == OREGISTER && t->op == OREGISTER) {
  1921  			if(f->val.u.reg != D_F0 || t->val.u.reg != D_F0)
  1922  				goto fatal;
  1923  			return;
  1924  		}
  1925  		if(f->op == OREGISTER)
  1926  			gins(AFMOVDP, f, t);
  1927  		else
  1928  			gins(AFMOVF, f, t);
  1929  		return;
  1930  
  1931  	case CASE(TFLOAT64, TFLOAT32):
  1932  		if(ismem(f) && ismem(t))
  1933  			goto hard;
  1934  		if(f->op == OREGISTER && t->op == OREGISTER) {
  1935  			tempname(&r1, types[TFLOAT32]);
  1936  			gins(AFMOVFP, f, &r1);
  1937  			gins(AFMOVF, &r1, t);
  1938  			return;
  1939  		}
  1940  		if(f->op == OREGISTER)
  1941  			gins(AFMOVFP, f, t);
  1942  		else
  1943  			gins(AFMOVD, f, t);
  1944  		return;
  1945  	}
  1946  
  1947  	gins(a, f, t);
  1948  	return;
  1949  
  1950  hard:
  1951  	// requires register intermediate
  1952  	regalloc(&r1, cvt, t);
  1953  	gmove(f, &r1);
  1954  	gmove(&r1, t);
  1955  	regfree(&r1);
  1956  	return;
  1957  
  1958  hardmem:
  1959  	// requires memory intermediate
  1960  	tempname(&r1, cvt);
  1961  	gmove(f, &r1);
  1962  	gmove(&r1, t);
  1963  	return;
  1964  
  1965  fatal:
  1966  	// should not happen
  1967  	fatal("gmove %lN -> %lN", f, t);
  1968  	return;
  1969  }
  1970  
  1971  static void
  1972  floatmove_sse(Node *f, Node *t)
  1973  {
  1974  	Node r1;
  1975  	Type *cvt;
  1976  	int a, ft, tt;
  1977  
  1978  	ft = simsimtype(f->type);
  1979  	tt = simsimtype(t->type);
  1980  
  1981  	switch(CASE(ft, tt)) {
  1982  	default:
  1983  		// should not happen
  1984  		fatal("gmove %N -> %N", f, t);
  1985  		return;
  1986  	/*
  1987  	* float to integer
  1988  	*/
  1989  	case CASE(TFLOAT32, TINT16):
  1990  	case CASE(TFLOAT32, TINT8):
  1991  	case CASE(TFLOAT32, TUINT16):
  1992  	case CASE(TFLOAT32, TUINT8):
  1993  	case CASE(TFLOAT64, TINT16):
  1994  	case CASE(TFLOAT64, TINT8):
  1995  	case CASE(TFLOAT64, TUINT16):
  1996  	case CASE(TFLOAT64, TUINT8):
  1997  		// convert via int32.
  1998  		cvt = types[TINT32];
  1999  		goto hard;
  2000  
  2001  	case CASE(TFLOAT32, TUINT32):
  2002  	case CASE(TFLOAT64, TUINT32):
  2003  		// convert via int64.
  2004  		cvt = types[TINT64];
  2005  		goto hardmem;
  2006  
  2007  	case CASE(TFLOAT32, TINT32):
  2008  		a = ACVTTSS2SL;
  2009  		goto rdst;
  2010  
  2011  	case CASE(TFLOAT64, TINT32):
  2012  		a = ACVTTSD2SL;
  2013  		goto rdst;
  2014  
  2015  	/*
  2016  	 * integer to float
  2017  	 */
  2018  	case CASE(TINT8, TFLOAT32):
  2019  	case CASE(TINT8, TFLOAT64):
  2020  	case CASE(TINT16, TFLOAT32):
  2021  	case CASE(TINT16, TFLOAT64):
  2022  	case CASE(TUINT16, TFLOAT32):
  2023  	case CASE(TUINT16, TFLOAT64):
  2024  	case CASE(TUINT8, TFLOAT32):
  2025  	case CASE(TUINT8, TFLOAT64):
  2026  		// convert via int32 memory
  2027  		cvt = types[TINT32];
  2028  		goto hard;
  2029  
  2030  	case CASE(TUINT32, TFLOAT32):
  2031  	case CASE(TUINT32, TFLOAT64):
  2032  		// convert via int64 memory
  2033  		cvt = types[TINT64];
  2034  		goto hardmem;
  2035  
  2036  	case CASE(TINT32, TFLOAT32):
  2037  		a = ACVTSL2SS;
  2038  		goto rdst;
  2039  
  2040  	case CASE(TINT32, TFLOAT64):
  2041  		a = ACVTSL2SD;
  2042  		goto rdst;
  2043  
  2044  	/*
  2045  	 * float to float
  2046  	 */
  2047  	case CASE(TFLOAT32, TFLOAT32):
  2048  		a = AMOVSS;
  2049  		break;
  2050  
  2051  	case CASE(TFLOAT64, TFLOAT64):
  2052  		a = AMOVSD;
  2053  		break;
  2054  
  2055  	case CASE(TFLOAT32, TFLOAT64):
  2056  		a = ACVTSS2SD;
  2057  		goto rdst;
  2058  
  2059  	case CASE(TFLOAT64, TFLOAT32):
  2060  		a = ACVTSD2SS;
  2061  		goto rdst;
  2062  	}
  2063  
  2064  	gins(a, f, t);
  2065  	return;
  2066  
  2067  hard:
  2068  	// requires register intermediate
  2069  	regalloc(&r1, cvt, t);
  2070  	gmove(f, &r1);
  2071  	gmove(&r1, t);
  2072  	regfree(&r1);
  2073  	return;
  2074  
  2075  hardmem:
  2076  	// requires memory intermediate
  2077  	tempname(&r1, cvt);
  2078  	gmove(f, &r1);
  2079  	gmove(&r1, t);
  2080  	return;
  2081  
  2082  rdst:
  2083  	// requires register destination
  2084  	regalloc(&r1, t->type, t);
  2085  	gins(a, f, &r1);
  2086  	gmove(&r1, t);
  2087  	regfree(&r1);
  2088  	return;
  2089  }
  2090  
  2091  int
  2092  samaddr(Node *f, Node *t)
  2093  {
  2094  
  2095  	if(f->op != t->op)
  2096  		return 0;
  2097  
  2098  	switch(f->op) {
  2099  	case OREGISTER:
  2100  		if(f->val.u.reg != t->val.u.reg)
  2101  			break;
  2102  		return 1;
  2103  	}
  2104  	return 0;
  2105  }
  2106  /*
  2107   * generate one instruction:
  2108   *	as f, t
  2109   */
  2110  Prog*
  2111  gins(int as, Node *f, Node *t)
  2112  {
  2113  	Prog *p;
  2114  	Addr af, at;
  2115  	int w;
  2116  
  2117  	if(as == AFMOVF && f && f->op == OREGISTER && t && t->op == OREGISTER)
  2118  		fatal("gins MOVF reg, reg");
  2119  	if(as == ACVTSD2SS && f && f->op == OLITERAL)
  2120  		fatal("gins CVTSD2SS const");
  2121  	if(as == AMOVSD && t && t->op == OREGISTER && t->val.u.reg == D_F0)
  2122  		fatal("gins MOVSD into F0");
  2123  
  2124  	switch(as) {
  2125  	case AMOVB:
  2126  	case AMOVW:
  2127  	case AMOVL:
  2128  		if(f != N && t != N && samaddr(f, t))
  2129  			return nil;
  2130  		break;
  2131  	
  2132  	case ALEAL:
  2133  		if(f != N && isconst(f, CTNIL))
  2134  			fatal("gins LEAL nil %T", f->type);
  2135  		break;
  2136  	}
  2137  
  2138  	memset(&af, 0, sizeof af);
  2139  	memset(&at, 0, sizeof at);
  2140  	if(f != N)
  2141  		naddr(f, &af, 1);
  2142  	if(t != N)
  2143  		naddr(t, &at, 1);
  2144  	p = prog(as);
  2145  	if(f != N)
  2146  		p->from = af;
  2147  	if(t != N)
  2148  		p->to = at;
  2149  	if(debug['g'])
  2150  		print("%P\n", p);
  2151  
  2152  	w = 0;
  2153  	switch(as) {
  2154  	case AMOVB:
  2155  		w = 1;
  2156  		break;
  2157  	case AMOVW:
  2158  		w = 2;
  2159  		break;
  2160  	case AMOVL:
  2161  		w = 4;
  2162  		break;
  2163  	}
  2164  
  2165  	if(1 && w != 0 && f != N && (af.width > w || at.width > w)) {
  2166  		dump("bad width from:", f);
  2167  		dump("bad width to:", t);
  2168  		fatal("bad width: %P (%d, %d)\n", p, af.width, at.width);
  2169  	}
  2170  
  2171  	return p;
  2172  }
  2173  
  2174  /*
  2175   * generate code to compute n;
  2176   * make a refer to result.
  2177   */
  2178  void
  2179  naddr(Node *n, Addr *a, int canemitcode)
  2180  {
  2181  	a->scale = 0;
  2182  	a->index = D_NONE;
  2183  	a->type = D_NONE;
  2184  	a->gotype = S;
  2185  	a->node = N;
  2186  	if(n == N)
  2187  		return;
  2188  
  2189  	switch(n->op) {
  2190  	default:
  2191  		fatal("naddr: bad %O %D", n->op, a);
  2192  		break;
  2193  
  2194  	case OREGISTER:
  2195  		a->type = n->val.u.reg;
  2196  		a->sym = S;
  2197  		break;
  2198  
  2199  	case OINDREG:
  2200  		a->type = n->val.u.reg+D_INDIR;
  2201  		a->sym = n->sym;
  2202  		a->offset = n->xoffset;
  2203  		break;
  2204  
  2205  	case OPARAM:
  2206  		// n->left is PHEAP ONAME for stack parameter.
  2207  		// compute address of actual parameter on stack.
  2208  		a->etype = n->left->type->etype;
  2209  		a->width = n->left->type->width;
  2210  		a->offset = n->xoffset;
  2211  		a->sym = n->left->sym;
  2212  		a->type = D_PARAM;
  2213  		a->node = n->left->orig;
  2214  		break;
  2215  
  2216  	case OCLOSUREVAR:
  2217  		a->type = D_DX+D_INDIR;
  2218  		a->offset = n->xoffset;
  2219  		a->sym = S;
  2220  		break;
  2221  
  2222  	case OCFUNC:
  2223  		naddr(n->left, a, canemitcode);
  2224  		a->sym = n->left->sym;
  2225  		break;
  2226  
  2227  	case ONAME:
  2228  		a->etype = 0;
  2229  		a->width = 0;
  2230  		if(n->type != T) {
  2231  			a->etype = simtype[n->type->etype];
  2232  			dowidth(n->type);
  2233  			a->width = n->type->width;
  2234  		}
  2235  		a->offset = n->xoffset;
  2236  		a->sym = n->sym;
  2237  		a->node = n->orig;
  2238  		//if(a->node >= (Node*)&n)
  2239  		//	fatal("stack node");
  2240  		if(a->sym == S)
  2241  			a->sym = lookup(".noname");
  2242  		if(n->method) {
  2243  			if(n->type != T)
  2244  			if(n->type->sym != S)
  2245  			if(n->type->sym->pkg != nil)
  2246  				a->sym = pkglookup(a->sym->name, n->type->sym->pkg);
  2247  		}
  2248  
  2249  		switch(n->class) {
  2250  		default:
  2251  			fatal("naddr: ONAME class %S %d\n", n->sym, n->class);
  2252  		case PEXTERN:
  2253  			a->type = D_EXTERN;
  2254  			break;
  2255  		case PAUTO:
  2256  			a->type = D_AUTO;
  2257  			break;
  2258  		case PPARAM:
  2259  		case PPARAMOUT:
  2260  			a->type = D_PARAM;
  2261  			break;
  2262  		case PFUNC:
  2263  			a->index = D_EXTERN;
  2264  			a->type = D_ADDR;
  2265  			a->sym = funcsym(a->sym);
  2266  			break;
  2267  		}
  2268  		break;
  2269  
  2270  	case OLITERAL:
  2271  		switch(n->val.ctype) {
  2272  		default:
  2273  			fatal("naddr: const %lT", n->type);
  2274  			break;
  2275  		case CTFLT:
  2276  			a->type = D_FCONST;
  2277  			a->u.dval = mpgetflt(n->val.u.fval);
  2278  			break;
  2279  		case CTINT:
  2280  		case CTRUNE:
  2281  			a->sym = S;
  2282  			a->type = D_CONST;
  2283  			a->offset = mpgetfix(n->val.u.xval);
  2284  			break;
  2285  		case CTSTR:
  2286  			datagostring(n->val.u.sval, a);
  2287  			break;
  2288  		case CTBOOL:
  2289  			a->sym = S;
  2290  			a->type = D_CONST;
  2291  			a->offset = n->val.u.bval;
  2292  			break;
  2293  		case CTNIL:
  2294  			a->sym = S;
  2295  			a->type = D_CONST;
  2296  			a->offset = 0;
  2297  			break;
  2298  		}
  2299  		break;
  2300  
  2301  	case OADDR:
  2302  		naddr(n->left, a, canemitcode);
  2303  		if(a->type >= D_INDIR) {
  2304  			a->type -= D_INDIR;
  2305  			break;
  2306  		}
  2307  		if(a->type == D_EXTERN || a->type == D_STATIC ||
  2308  		   a->type == D_AUTO || a->type == D_PARAM)
  2309  			if(a->index == D_NONE) {
  2310  				a->index = a->type;
  2311  				a->type = D_ADDR;
  2312  				break;
  2313  			}
  2314  		fatal("naddr: OADDR\n");
  2315  	
  2316  	case OITAB:
  2317  		// itable of interface value
  2318  		naddr(n->left, a, canemitcode);
  2319  		if(a->type == D_CONST && a->offset == 0)
  2320  			break;	// len(nil)
  2321  		a->etype = tptr;
  2322  		a->width = widthptr;
  2323  		break;
  2324  
  2325  	case OSPTR:
  2326  		// pointer in a string or slice
  2327  		naddr(n->left, a, canemitcode);
  2328  		if(a->type == D_CONST && a->offset == 0)
  2329  			break;	// ptr(nil)
  2330  		a->etype = simtype[TUINTPTR];
  2331  		a->offset += Array_array;
  2332  		a->width = widthptr;
  2333  		break;
  2334  
  2335  	case OLEN:
  2336  		// len of string or slice
  2337  		naddr(n->left, a, canemitcode);
  2338  		if(a->type == D_CONST && a->offset == 0)
  2339  			break;	// len(nil)
  2340  		a->etype = TUINT32;
  2341  		a->offset += Array_nel;
  2342  		a->width = 4;
  2343  		break;
  2344  
  2345  	case OCAP:
  2346  		// cap of string or slice
  2347  		naddr(n->left, a, canemitcode);
  2348  		if(a->type == D_CONST && a->offset == 0)
  2349  			break;	// cap(nil)
  2350  		a->etype = TUINT32;
  2351  		a->offset += Array_cap;
  2352  		a->width = 4;
  2353  		break;
  2354  
  2355  //	case OADD:
  2356  //		if(n->right->op == OLITERAL) {
  2357  //			v = n->right->vconst;
  2358  //			naddr(n->left, a, canemitcode);
  2359  //		} else
  2360  //		if(n->left->op == OLITERAL) {
  2361  //			v = n->left->vconst;
  2362  //			naddr(n->right, a, canemitcode);
  2363  //		} else
  2364  //			goto bad;
  2365  //		a->offset += v;
  2366  //		break;
  2367  
  2368  	}
  2369  }
  2370  
  2371  int
  2372  dotaddable(Node *n, Node *n1)
  2373  {
  2374  	int o;
  2375  	int64 oary[10];
  2376  	Node *nn;
  2377  
  2378  	if(n->op != ODOT)
  2379  		return 0;
  2380  
  2381  	o = dotoffset(n, oary, &nn);
  2382  	if(nn != N && nn->addable && o == 1 && oary[0] >= 0) {
  2383  		*n1 = *nn;
  2384  		n1->type = n->type;
  2385  		n1->xoffset += oary[0];
  2386  		return 1;
  2387  	}
  2388  	return 0;
  2389  }
  2390  
  2391  void
  2392  sudoclean(void)
  2393  {
  2394  }
  2395  
  2396  int
  2397  sudoaddable(int as, Node *n, Addr *a)
  2398  {
  2399  	USED(as);
  2400  	USED(n);
  2401  	USED(a);
  2402  
  2403  	return 0;
  2404  }