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