github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/6c/txt.c (about)

     1  // Inferno utils/6c/txt.c
     2  // http://code.google.com/p/inferno-os/source/browse/utils/6c/txt.c
     3  //
     4  //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
     5  //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
     6  //	Portions Copyright © 1997-1999 Vita Nuova Limited
     7  //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
     8  //	Portions Copyright © 2004,2006 Bruce Ellis
     9  //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    10  //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    11  //	Portions Copyright © 2009 The Go Authors.  All rights reserved.
    12  //
    13  // Permission is hereby granted, free of charge, to any person obtaining a copy
    14  // of this software and associated documentation files (the "Software"), to deal
    15  // in the Software without restriction, including without limitation the rights
    16  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    17  // copies of the Software, and to permit persons to whom the Software is
    18  // furnished to do so, subject to the following conditions:
    19  //
    20  // The above copyright notice and this permission notice shall be included in
    21  // all copies or substantial portions of the Software.
    22  //
    23  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    24  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    25  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    26  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    27  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    28  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    29  // THE SOFTWARE.
    30  
    31  #include "gc.h"
    32  
    33  void
    34  ginit(void)
    35  {
    36  	int i;
    37  	Type *t;
    38  
    39  	thechar = '6';
    40  	thestring = "amd64";
    41  	dodefine("_64BIT");
    42  	listinit();
    43  	nstring = 0;
    44  	mnstring = 0;
    45  	nrathole = 0;
    46  	pc = 0;
    47  	breakpc = -1;
    48  	continpc = -1;
    49  	cases = C;
    50  	firstp = P;
    51  	lastp = P;
    52  	tfield = types[TINT];
    53  
    54  	typeword = typechlvp;
    55  	typecmplx = typesu;
    56  
    57  	/* TO DO */
    58  	memmove(typechlpv, typechlp, sizeof(typechlpv));
    59  	typechlpv[TVLONG] = 1;
    60  	typechlpv[TUVLONG] = 1;
    61  
    62  	zprog.link = P;
    63  	zprog.as = AGOK;
    64  	zprog.from.type = D_NONE;
    65  	zprog.from.index = D_NONE;
    66  	zprog.from.scale = 0;
    67  	zprog.to = zprog.from;
    68  
    69  	lregnode.op = OREGISTER;
    70  	lregnode.class = CEXREG;
    71  	lregnode.reg = REGTMP;
    72  	lregnode.complex = 0;
    73  	lregnode.addable = 11;
    74  	lregnode.type = types[TLONG];
    75  
    76  	qregnode = lregnode;
    77  	qregnode.type = types[TVLONG];
    78  
    79  	constnode.op = OCONST;
    80  	constnode.class = CXXX;
    81  	constnode.complex = 0;
    82  	constnode.addable = 20;
    83  	constnode.type = types[TLONG];
    84  
    85  	vconstnode = constnode;
    86  	vconstnode.type = types[TVLONG];
    87  
    88  	fconstnode.op = OCONST;
    89  	fconstnode.class = CXXX;
    90  	fconstnode.complex = 0;
    91  	fconstnode.addable = 20;
    92  	fconstnode.type = types[TDOUBLE];
    93  
    94  	nodsafe = new(ONAME, Z, Z);
    95  	nodsafe->sym = slookup(".safe");
    96  	nodsafe->type = types[TINT];
    97  	nodsafe->etype = types[TINT]->etype;
    98  	nodsafe->class = CAUTO;
    99  	complex(nodsafe);
   100  
   101  	t = typ(TARRAY, types[TCHAR]);
   102  	symrathole = slookup(".rathole");
   103  	symrathole->class = CGLOBL;
   104  	symrathole->type = t;
   105  
   106  	nodrat = new(ONAME, Z, Z);
   107  	nodrat->sym = symrathole;
   108  	nodrat->type = types[TIND];
   109  	nodrat->etype = TVOID;
   110  	nodrat->class = CGLOBL;
   111  	complex(nodrat);
   112  	nodrat->type = t;
   113  
   114  	nodret = new(ONAME, Z, Z);
   115  	nodret->sym = slookup(".ret");
   116  	nodret->type = types[TIND];
   117  	nodret->etype = TIND;
   118  	nodret->class = CPARAM;
   119  	nodret = new(OIND, nodret, Z);
   120  	complex(nodret);
   121  
   122  	if(0)
   123  		com64init();
   124  
   125  	for(i=0; i<nelem(reg); i++) {
   126  		reg[i] = 1;
   127  		if(i >= D_AX && i <= D_R15 && i != D_SP)
   128  			reg[i] = 0;
   129  		if(i >= D_X0 && i <= D_X7)
   130  			reg[i] = 0;
   131  	}
   132  }
   133  
   134  void
   135  gclean(void)
   136  {
   137  	int i;
   138  	Sym *s;
   139  
   140  	reg[D_SP]--;
   141  	for(i=D_AX; i<=D_R15; i++)
   142  		if(reg[i])
   143  			diag(Z, "reg %R left allocated", i);
   144  	for(i=D_X0; i<=D_X7; i++)
   145  		if(reg[i])
   146  			diag(Z, "reg %R left allocated", i);
   147  	while(mnstring)
   148  		outstring("", 1L);
   149  	symstring->type->width = nstring;
   150  	symrathole->type->width = nrathole;
   151  	for(i=0; i<NHASH; i++)
   152  	for(s = hash[i]; s != S; s = s->link) {
   153  		if(s->type == T)
   154  			continue;
   155  		if(s->type->width == 0)
   156  			continue;
   157  		if(s->class != CGLOBL && s->class != CSTATIC)
   158  			continue;
   159  		if(s->type == types[TENUM])
   160  			continue;
   161  		textflag = s->dataflag;
   162  		gpseudo(AGLOBL, s, nodconst(s->type->width));
   163  		textflag = 0;
   164  	}
   165  	nextpc();
   166  	p->as = AEND;
   167  	outcode();
   168  }
   169  
   170  void
   171  nextpc(void)
   172  {
   173  
   174  	p = alloc(sizeof(*p));
   175  	*p = zprog;
   176  	p->lineno = nearln;
   177  	pc++;
   178  	if(firstp == P) {
   179  		firstp = p;
   180  		lastp = p;
   181  		return;
   182  	}
   183  	lastp->link = p;
   184  	lastp = p;
   185  }
   186  
   187  void
   188  gargs(Node *n, Node *tn1, Node *tn2)
   189  {
   190  	int32 regs;
   191  	Node fnxargs[20], *fnxp;
   192  
   193  	regs = cursafe;
   194  
   195  	fnxp = fnxargs;
   196  	garg1(n, tn1, tn2, 0, &fnxp);	/* compile fns to temps */
   197  
   198  	curarg = 0;
   199  	fnxp = fnxargs;
   200  	garg1(n, tn1, tn2, 1, &fnxp);	/* compile normal args and temps */
   201  
   202  	cursafe = regs;
   203  }
   204  
   205  int
   206  nareg(void)
   207  {
   208  	int i, n;
   209  
   210  	n = 0;
   211  	for(i=D_AX; i<=D_R15; i++)
   212  		if(reg[i] == 0)
   213  			n++;
   214  	return n;
   215  }
   216  
   217  void
   218  garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
   219  {
   220  	Node nod;
   221  
   222  	if(n == Z)
   223  		return;
   224  	if(n->op == OLIST) {
   225  		garg1(n->left, tn1, tn2, f, fnxp);
   226  		garg1(n->right, tn1, tn2, f, fnxp);
   227  		return;
   228  	}
   229  	if(f == 0) {
   230  		if(n->complex >= FNX) {
   231  			regsalloc(*fnxp, n);
   232  			nod = znode;
   233  			nod.op = OAS;
   234  			nod.left = *fnxp;
   235  			nod.right = n;
   236  			nod.type = n->type;
   237  			cgen(&nod, Z);
   238  			(*fnxp)++;
   239  		}
   240  		return;
   241  	}
   242  	if(typesu[n->type->etype]) {
   243  		regaalloc(tn2, n);
   244  		if(n->complex >= FNX) {
   245  			sugen(*fnxp, tn2, n->type->width);
   246  			(*fnxp)++;
   247  		} else
   248  			sugen(n, tn2, n->type->width);
   249  		return;
   250  	}
   251  	if(REGARG >= 0 && curarg == 0 && typechlpv[n->type->etype]) {
   252  		regaalloc1(tn1, n);
   253  		if(n->complex >= FNX) {
   254  			cgen(*fnxp, tn1);
   255  			(*fnxp)++;
   256  		} else
   257  			cgen(n, tn1);
   258  		return;
   259  	}
   260  	if(vconst(n) == 0) {
   261  		regaalloc(tn2, n);
   262  		gmove(n, tn2);
   263  		return;
   264  	}
   265  	regalloc(tn1, n, Z);
   266  	if(n->complex >= FNX) {
   267  		cgen(*fnxp, tn1);
   268  		(*fnxp)++;
   269  	} else
   270  		cgen(n, tn1);
   271  	regaalloc(tn2, n);
   272  	gmove(tn1, tn2);
   273  	regfree(tn1);
   274  }
   275  
   276  Node*
   277  nodgconst(vlong v, Type *t)
   278  {
   279  	if(!typev[t->etype])
   280  		return nodconst((int32)v);
   281  	vconstnode.vconst = v;
   282  	return &vconstnode;
   283  }
   284  
   285  Node*
   286  nodconst(int32 v)
   287  {
   288  	constnode.vconst = v;
   289  	return &constnode;
   290  }
   291  
   292  Node*
   293  nodfconst(double d)
   294  {
   295  	fconstnode.fconst = d;
   296  	return &fconstnode;
   297  }
   298  
   299  int
   300  isreg(Node *n, int r)
   301  {
   302  
   303  	if(n->op == OREGISTER)
   304  		if(n->reg == r)
   305  			return 1;
   306  	return 0;
   307  }
   308  
   309  int
   310  nodreg(Node *n, Node *nn, int r)
   311  {
   312  	int et;
   313  
   314  	*n = qregnode;
   315  	n->reg = r;
   316  	if(nn != Z){
   317  		et = nn->type->etype;
   318  		if(!typefd[et] && nn->type->width <= SZ_LONG && 0)
   319  			n->type = typeu[et]? types[TUINT]: types[TINT];
   320  		else
   321  			n->type = nn->type;
   322  //print("nodreg %s [%s]\n", tnames[et], tnames[n->type->etype]);
   323  		n->lineno = nn->lineno;
   324  	}
   325  	if(reg[r] == 0)
   326  		return 0;
   327  	if(nn != Z) {
   328  		if(nn->op == OREGISTER)
   329  		if(nn->reg == r)
   330  			return 0;
   331  	}
   332  	return 1;
   333  }
   334  
   335  void
   336  regret(Node *n, Node *nn)
   337  {
   338  	int r;
   339  
   340  	r = REGRET;
   341  	if(typefd[nn->type->etype])
   342  		r = FREGRET;
   343  	nodreg(n, nn, r);
   344  	reg[r]++;
   345  }
   346  
   347  void
   348  regalloc(Node *n, Node *tn, Node *o)
   349  {
   350  	int i;
   351  
   352  	switch(tn->type->etype) {
   353  	case TCHAR:
   354  	case TUCHAR:
   355  	case TSHORT:
   356  	case TUSHORT:
   357  	case TINT:
   358  	case TUINT:
   359  	case TLONG:
   360  	case TULONG:
   361  	case TVLONG:
   362  	case TUVLONG:
   363  	case TIND:
   364  		if(o != Z && o->op == OREGISTER) {
   365  			i = o->reg;
   366  			if(i >= D_AX && i <= D_R15)
   367  				goto out;
   368  		}
   369  		for(i=D_AX; i<=D_R15; i++)
   370  			if(reg[i] == 0)
   371  				goto out;
   372  		diag(tn, "out of fixed registers");
   373  		goto err;
   374  
   375  	case TFLOAT:
   376  	case TDOUBLE:
   377  		if(o != Z && o->op == OREGISTER) {
   378  			i = o->reg;
   379  			if(i >= D_X0 && i <= D_X7)
   380  				goto out;
   381  		}
   382  		for(i=D_X0; i<=D_X7; i++)
   383  			if(reg[i] == 0)
   384  				goto out;
   385  		diag(tn, "out of float registers");
   386  		goto out;
   387  	}
   388  	diag(tn, "unknown type in regalloc: %T", tn->type);
   389  err:
   390  	i = 0;
   391  out:
   392  	if(i)
   393  		reg[i]++;
   394  	nodreg(n, tn, i);
   395  }
   396  
   397  void
   398  regialloc(Node *n, Node *tn, Node *o)
   399  {
   400  	Node nod;
   401  
   402  	nod = *tn;
   403  	nod.type = types[TIND];
   404  	regalloc(n, &nod, o);
   405  }
   406  
   407  void
   408  regfree(Node *n)
   409  {
   410  	int i;
   411  
   412  	i = 0;
   413  	if(n->op != OREGISTER && n->op != OINDREG)
   414  		goto err;
   415  	i = n->reg;
   416  	if(i < 0 || i >= nelem(reg))
   417  		goto err;
   418  	if(reg[i] <= 0)
   419  		goto err;
   420  	reg[i]--;
   421  	return;
   422  err:
   423  	diag(n, "error in regfree: %R", i);
   424  }
   425  
   426  void
   427  regsalloc(Node *n, Node *nn)
   428  {
   429  	cursafe = align(cursafe, nn->type, Aaut3, nil);
   430  	maxargsafe = maxround(maxargsafe, cursafe+curarg);
   431  	*n = *nodsafe;
   432  	n->xoffset = -(stkoff + cursafe);
   433  	n->type = nn->type;
   434  	n->etype = nn->type->etype;
   435  	n->lineno = nn->lineno;
   436  }
   437  
   438  void
   439  regaalloc1(Node *n, Node *nn)
   440  {
   441  	if(REGARG < 0) {
   442  		fatal(n, "regaalloc1 and REGARG<0");
   443  		return;
   444  	}
   445  	nodreg(n, nn, REGARG);
   446  	reg[REGARG]++;
   447  	curarg = align(curarg, nn->type, Aarg1, nil);
   448  	curarg = align(curarg, nn->type, Aarg2, nil);
   449  	maxargsafe = maxround(maxargsafe, cursafe+curarg);
   450  }
   451  
   452  void
   453  regaalloc(Node *n, Node *nn)
   454  {
   455  	curarg = align(curarg, nn->type, Aarg1, nil);
   456  	*n = *nn;
   457  	n->op = OINDREG;
   458  	n->reg = REGSP;
   459  	n->xoffset = curarg;
   460  	n->complex = 0;
   461  	n->addable = 20;
   462  	curarg = align(curarg, nn->type, Aarg2, nil);
   463  	maxargsafe = maxround(maxargsafe, cursafe+curarg);
   464  }
   465  
   466  void
   467  regind(Node *n, Node *nn)
   468  {
   469  
   470  	if(n->op != OREGISTER) {
   471  		diag(n, "regind not OREGISTER");
   472  		return;
   473  	}
   474  	n->op = OINDREG;
   475  	n->type = nn->type;
   476  }
   477  
   478  void
   479  naddr(Node *n, Adr *a)
   480  {
   481  	int32 v;
   482  
   483  	a->type = D_NONE;
   484  	if(n == Z)
   485  		return;
   486  	switch(n->op) {
   487  	default:
   488  	bad:
   489  		diag(n, "bad in naddr: %O %D", n->op, a);
   490  		break;
   491  
   492  	case OREGISTER:
   493  		a->type = n->reg;
   494  		a->sym = S;
   495  		break;
   496  
   497  	case OEXREG:
   498  		a->type = D_INDIR + D_GS;
   499  		a->offset = n->reg - 1;
   500  		break;
   501  
   502  	case OIND:
   503  		naddr(n->left, a);
   504  		if(a->type >= D_AX && a->type <= D_R15)
   505  			a->type += D_INDIR;
   506  		else
   507  		if(a->type == D_CONST)
   508  			a->type = D_NONE+D_INDIR;
   509  		else
   510  		if(a->type == D_ADDR) {
   511  			a->type = a->index;
   512  			a->index = D_NONE;
   513  		} else
   514  			goto bad;
   515  		break;
   516  
   517  	case OINDEX:
   518  		a->type = idx.ptr;
   519  		if(n->left->op == OADDR || n->left->op == OCONST)
   520  			naddr(n->left, a);
   521  		if(a->type >= D_AX && a->type <= D_R15)
   522  			a->type += D_INDIR;
   523  		else
   524  		if(a->type == D_CONST)
   525  			a->type = D_NONE+D_INDIR;
   526  		else
   527  		if(a->type == D_ADDR) {
   528  			a->type = a->index;
   529  			a->index = D_NONE;
   530  		} else
   531  			goto bad;
   532  		a->index = idx.reg;
   533  		a->scale = n->scale;
   534  		a->offset += n->xoffset;
   535  		break;
   536  
   537  	case OINDREG:
   538  		a->type = n->reg+D_INDIR;
   539  		a->sym = S;
   540  		a->offset = n->xoffset;
   541  		break;
   542  
   543  	case ONAME:
   544  		a->etype = n->etype;
   545  		a->type = D_STATIC;
   546  		a->sym = n->sym;
   547  		a->offset = n->xoffset;
   548  		if(n->class == CSTATIC)
   549  			break;
   550  		if(n->class == CEXTERN || n->class == CGLOBL) {
   551  			a->type = D_EXTERN;
   552  			break;
   553  		}
   554  		if(n->class == CAUTO) {
   555  			a->type = D_AUTO;
   556  			break;
   557  		}
   558  		if(n->class == CPARAM) {
   559  			a->type = D_PARAM;
   560  			break;
   561  		}
   562  		goto bad;
   563  
   564  	case OCONST:
   565  		if(typefd[n->type->etype]) {
   566  			a->type = D_FCONST;
   567  			a->dval = n->fconst;
   568  			break;
   569  		}
   570  		a->sym = S;
   571  		a->type = D_CONST;
   572  		if(typev[n->type->etype] || n->type->etype == TIND)
   573  			a->offset = n->vconst;
   574  		else
   575  			a->offset = convvtox(n->vconst, typeu[n->type->etype]? TULONG: TLONG);
   576  		break;
   577  
   578  	case OADDR:
   579  		naddr(n->left, a);
   580  		if(a->type >= D_INDIR) {
   581  			a->type -= D_INDIR;
   582  			break;
   583  		}
   584  		if(a->type == D_EXTERN || a->type == D_STATIC ||
   585  		   a->type == D_AUTO || a->type == D_PARAM)
   586  			if(a->index == D_NONE) {
   587  				a->index = a->type;
   588  				a->type = D_ADDR;
   589  				break;
   590  			}
   591  		goto bad;
   592  
   593  	case OADD:
   594  		if(n->right->op == OCONST) {
   595  			v = n->right->vconst;
   596  			naddr(n->left, a);
   597  		} else
   598  		if(n->left->op == OCONST) {
   599  			v = n->left->vconst;
   600  			naddr(n->right, a);
   601  		} else
   602  			goto bad;
   603  		a->offset += v;
   604  		break;
   605  
   606  	}
   607  }
   608  
   609  void
   610  gcmp(int op, Node *n, vlong val)
   611  {
   612  	Node *cn, nod;
   613  
   614  	cn = nodgconst(val, n->type);
   615  	if(!immconst(cn)){
   616  		regalloc(&nod, n, Z);
   617  		gmove(cn, &nod);
   618  		gopcode(op, n->type, n, &nod);
   619  		regfree(&nod);
   620  	}else
   621  		gopcode(op, n->type, n, cn);
   622  }
   623  
   624  #define	CASE(a,b)	((a<<8)|(b<<0))
   625  
   626  void
   627  gmove(Node *f, Node *t)
   628  {
   629  	int ft, tt, t64, a;
   630  	Node nod, nod1, nod2, nod3;
   631  	Prog *p1, *p2;
   632  
   633  	ft = f->type->etype;
   634  	tt = t->type->etype;
   635  	t64 = tt == TVLONG || tt == TUVLONG || tt == TIND;
   636  	if(debug['M'])
   637  		print("gop: %O %O[%s],%O[%s]\n", OAS,
   638  			f->op, tnames[ft], t->op, tnames[tt]);
   639  	if(typefd[ft] && f->op == OCONST) {
   640  		/* TO DO: pick up special constants, possibly preloaded */
   641  		if(f->fconst == 0.0){
   642  			regalloc(&nod, t, t);
   643  			gins(AXORPD, &nod, &nod);
   644  			gmove(&nod, t);
   645  			regfree(&nod);
   646  			return;
   647  		}
   648  	}
   649  /*
   650   * load
   651   */
   652  	if(ft == TVLONG || ft == TUVLONG)
   653  	if(f->op == OCONST)
   654  	if(f->vconst > 0x7fffffffLL || f->vconst < -0x7fffffffLL)
   655  	if(t->op != OREGISTER) {
   656  		regalloc(&nod, f, Z);
   657  		gmove(f, &nod);
   658  		gmove(&nod, t);
   659  		regfree(&nod);
   660  		return;
   661  	}
   662  
   663  	if(f->op == ONAME || f->op == OINDREG ||
   664  	   f->op == OIND || f->op == OINDEX)
   665  	switch(ft) {
   666  	case TCHAR:
   667  		a = AMOVBLSX;
   668  		if(t64)
   669  			a = AMOVBQSX;
   670  		goto ld;
   671  	case TUCHAR:
   672  		a = AMOVBLZX;
   673  		if(t64)
   674  			a = AMOVBQZX;
   675  		goto ld;
   676  	case TSHORT:
   677  		a = AMOVWLSX;
   678  		if(t64)
   679  			a = AMOVWQSX;
   680  		goto ld;
   681  	case TUSHORT:
   682  		a = AMOVWLZX;
   683  		if(t64)
   684  			a = AMOVWQZX;
   685  		goto ld;
   686  	case TINT:
   687  	case TLONG:
   688  		if(typefd[tt]) {
   689  			regalloc(&nod, t, t);
   690  			if(tt == TDOUBLE)
   691  				a = ACVTSL2SD;
   692  			else
   693  				a = ACVTSL2SS;
   694  			gins(a, f, &nod);
   695  			gmove(&nod, t);
   696  			regfree(&nod);
   697  			return;
   698  		}
   699  		a = AMOVL;
   700  		if(t64)
   701  			a = AMOVLQSX;
   702  		goto ld;
   703  	case TUINT:
   704  	case TULONG:
   705  		a = AMOVL;
   706  		if(t64)
   707  			a = AMOVLQZX;	/* could probably use plain MOVL */
   708  		goto ld;
   709  	case TVLONG:
   710  		if(typefd[tt]) {
   711  			regalloc(&nod, t, t);
   712  			if(tt == TDOUBLE)
   713  				a = ACVTSQ2SD;
   714  			else
   715  				a = ACVTSQ2SS;
   716  			gins(a, f, &nod);
   717  			gmove(&nod, t);
   718  			regfree(&nod);
   719  			return;
   720  		}
   721  	case TUVLONG:
   722  		a = AMOVQ;
   723  		goto ld;
   724  	case TIND:
   725  		a = AMOVQ;
   726  
   727  	ld:
   728  		regalloc(&nod, f, t);
   729  		nod.type = t64? types[TVLONG]: types[TINT];
   730  		gins(a, f, &nod);
   731  		gmove(&nod, t);
   732  		regfree(&nod);
   733  		return;
   734  
   735  	case TFLOAT:
   736  		a = AMOVSS;
   737  		goto fld;
   738  	case TDOUBLE:
   739  		a = AMOVSD;
   740  	fld:
   741  		regalloc(&nod, f, t);
   742  		if(tt != TDOUBLE && tt != TFLOAT){	/* TO DO: why is this here */
   743  			prtree(f, "odd tree");
   744  			nod.type = t64? types[TVLONG]: types[TINT];
   745  		}
   746  		gins(a, f, &nod);
   747  		gmove(&nod, t);
   748  		regfree(&nod);
   749  		return;
   750  	}
   751  
   752  /*
   753   * store
   754   */
   755  	if(t->op == ONAME || t->op == OINDREG ||
   756  	   t->op == OIND || t->op == OINDEX)
   757  	switch(tt) {
   758  	case TCHAR:
   759  	case TUCHAR:
   760  		a = AMOVB;	goto st;
   761  	case TSHORT:
   762  	case TUSHORT:
   763  		a = AMOVW;	goto st;
   764  	case TINT:
   765  	case TUINT:
   766  	case TLONG:
   767  	case TULONG:
   768  		a = AMOVL;	goto st;
   769  	case TVLONG:
   770  	case TUVLONG:
   771  	case TIND:
   772  		a = AMOVQ;	goto st;
   773  
   774  	st:
   775  		if(f->op == OCONST) {
   776  			gins(a, f, t);
   777  			return;
   778  		}
   779  	fst:
   780  		regalloc(&nod, t, f);
   781  		gmove(f, &nod);
   782  		gins(a, &nod, t);
   783  		regfree(&nod);
   784  		return;
   785  
   786  	case TFLOAT:
   787  		a = AMOVSS;
   788  		goto fst;
   789  	case TDOUBLE:
   790  		a = AMOVSD;
   791  		goto fst;
   792  	}
   793  
   794  /*
   795   * convert
   796   */
   797  	switch(CASE(ft,tt)) {
   798  	default:
   799  /*
   800   * integer to integer
   801   ********
   802  		a = AGOK;	break;
   803  
   804  	case CASE(	TCHAR,	TCHAR):
   805  	case CASE(	TUCHAR,	TCHAR):
   806  	case CASE(	TSHORT,	TCHAR):
   807  	case CASE(	TUSHORT,TCHAR):
   808  	case CASE(	TINT,	TCHAR):
   809  	case CASE(	TUINT,	TCHAR):
   810  	case CASE(	TLONG,	TCHAR):
   811  	case CASE(	TULONG,	TCHAR):
   812  
   813  	case CASE(	TCHAR,	TUCHAR):
   814  	case CASE(	TUCHAR,	TUCHAR):
   815  	case CASE(	TSHORT,	TUCHAR):
   816  	case CASE(	TUSHORT,TUCHAR):
   817  	case CASE(	TINT,	TUCHAR):
   818  	case CASE(	TUINT,	TUCHAR):
   819  	case CASE(	TLONG,	TUCHAR):
   820  	case CASE(	TULONG,	TUCHAR):
   821  
   822  	case CASE(	TSHORT,	TSHORT):
   823  	case CASE(	TUSHORT,TSHORT):
   824  	case CASE(	TINT,	TSHORT):
   825  	case CASE(	TUINT,	TSHORT):
   826  	case CASE(	TLONG,	TSHORT):
   827  	case CASE(	TULONG,	TSHORT):
   828  
   829  	case CASE(	TSHORT,	TUSHORT):
   830  	case CASE(	TUSHORT,TUSHORT):
   831  	case CASE(	TINT,	TUSHORT):
   832  	case CASE(	TUINT,	TUSHORT):
   833  	case CASE(	TLONG,	TUSHORT):
   834  	case CASE(	TULONG,	TUSHORT):
   835  
   836  	case CASE(	TINT,	TINT):
   837  	case CASE(	TUINT,	TINT):
   838  	case CASE(	TLONG,	TINT):
   839  	case CASE(	TULONG,	TINT):
   840  
   841  	case CASE(	TINT,	TUINT):
   842  	case CASE(	TUINT,	TUINT):
   843  	case CASE(	TLONG,	TUINT):
   844  	case CASE(	TULONG,	TUINT):
   845   *****/
   846  		a = AMOVL;
   847  		break;
   848  
   849  	case CASE(	TINT,	TIND):
   850  	case CASE(	TINT,	TVLONG):
   851  	case CASE(	TINT,	TUVLONG):
   852  	case CASE(	TLONG,	TIND):
   853  	case CASE(	TLONG,	TVLONG):
   854  	case CASE(	TLONG,	TUVLONG):
   855  		a = AMOVLQSX;
   856  		if(f->op == OCONST) {
   857  			f->vconst &= (uvlong)0xffffffffU;
   858  			if(f->vconst & 0x80000000)
   859  				f->vconst |= (vlong)0xffffffff << 32;
   860  			a = AMOVQ;
   861  		}
   862  		break;
   863  
   864  	case CASE(	TUINT,	TIND):
   865  	case CASE(	TUINT,	TVLONG):
   866  	case CASE(	TUINT,	TUVLONG):
   867  	case CASE(	TULONG,	TVLONG):
   868  	case CASE(	TULONG,	TUVLONG):
   869  	case CASE(	TULONG,	TIND):
   870  		a = AMOVLQZX;
   871  		if(f->op == OCONST) {
   872  			f->vconst &= (uvlong)0xffffffffU;
   873  			a = AMOVQ;
   874  		}
   875  		break;
   876  	
   877  	case CASE(	TIND,	TCHAR):
   878  	case CASE(	TIND,	TUCHAR):
   879  	case CASE(	TIND,	TSHORT):
   880  	case CASE(	TIND,	TUSHORT):
   881  	case CASE(	TIND,	TINT):
   882  	case CASE(	TIND,	TUINT):
   883  	case CASE(	TIND,	TLONG):
   884  	case CASE(	TIND,	TULONG):
   885  	case CASE(	TVLONG,	TCHAR):
   886  	case CASE(	TVLONG,	TUCHAR):
   887  	case CASE(	TVLONG,	TSHORT):
   888  	case CASE(	TVLONG,	TUSHORT):
   889  	case CASE(	TVLONG,	TINT):
   890  	case CASE(	TVLONG,	TUINT):
   891  	case CASE(	TVLONG,	TLONG):
   892  	case CASE(	TVLONG,	TULONG):
   893  	case CASE(	TUVLONG,	TCHAR):
   894  	case CASE(	TUVLONG,	TUCHAR):
   895  	case CASE(	TUVLONG,	TSHORT):
   896  	case CASE(	TUVLONG,	TUSHORT):
   897  	case CASE(	TUVLONG,	TINT):
   898  	case CASE(	TUVLONG,	TUINT):
   899  	case CASE(	TUVLONG,	TLONG):
   900  	case CASE(	TUVLONG,	TULONG):
   901  		a = AMOVQL;
   902  		if(f->op == OCONST) {
   903  			f->vconst &= (int)0xffffffffU;
   904  			a = AMOVL;
   905  		}
   906  		break;	
   907  
   908  	case CASE(	TIND,	TIND):
   909  	case CASE(	TIND,	TVLONG):
   910  	case CASE(	TIND,	TUVLONG):
   911  	case CASE(	TVLONG,	TIND):
   912  	case CASE(	TVLONG,	TVLONG):
   913  	case CASE(	TVLONG,	TUVLONG):
   914  	case CASE(	TUVLONG,	TIND):
   915  	case CASE(	TUVLONG,	TVLONG):
   916  	case CASE(	TUVLONG,	TUVLONG):
   917  		a = AMOVQ;
   918  		break;
   919  
   920  	case CASE(	TSHORT,	TINT):
   921  	case CASE(	TSHORT,	TUINT):
   922  	case CASE(	TSHORT,	TLONG):
   923  	case CASE(	TSHORT,	TULONG):
   924  		a = AMOVWLSX;
   925  		if(f->op == OCONST) {
   926  			f->vconst &= 0xffff;
   927  			if(f->vconst & 0x8000)
   928  				f->vconst |= 0xffff0000;
   929  			a = AMOVL;
   930  		}
   931  		break;
   932  
   933  	case CASE(	TSHORT,	TVLONG):
   934  	case CASE(	TSHORT,	TUVLONG):
   935  	case CASE(	TSHORT,	TIND):
   936  		a = AMOVWQSX;
   937  		if(f->op == OCONST) {
   938  			f->vconst &= 0xffff;
   939  			if(f->vconst & 0x8000){
   940  				f->vconst |= 0xffff0000;
   941  				f->vconst |= (vlong)~0 << 32;
   942  			}
   943  			a = AMOVL;
   944  		}
   945  		break;
   946  
   947  	case CASE(	TUSHORT,TINT):
   948  	case CASE(	TUSHORT,TUINT):
   949  	case CASE(	TUSHORT,TLONG):
   950  	case CASE(	TUSHORT,TULONG):
   951  		a = AMOVWLZX;
   952  		if(f->op == OCONST) {
   953  			f->vconst &= 0xffff;
   954  			a = AMOVL;
   955  		}
   956  		break;
   957  
   958  	case CASE(	TUSHORT,TVLONG):
   959  	case CASE(	TUSHORT,TUVLONG):
   960  	case CASE(	TUSHORT,TIND):
   961  		a = AMOVWQZX;
   962  		if(f->op == OCONST) {
   963  			f->vconst &= 0xffff;
   964  			a = AMOVL;	/* MOVL also zero-extends to 64 bits */
   965  		}
   966  		break;
   967  
   968  	case CASE(	TCHAR,	TSHORT):
   969  	case CASE(	TCHAR,	TUSHORT):
   970  	case CASE(	TCHAR,	TINT):
   971  	case CASE(	TCHAR,	TUINT):
   972  	case CASE(	TCHAR,	TLONG):
   973  	case CASE(	TCHAR,	TULONG):
   974  		a = AMOVBLSX;
   975  		if(f->op == OCONST) {
   976  			f->vconst &= 0xff;
   977  			if(f->vconst & 0x80)
   978  				f->vconst |= 0xffffff00;
   979  			a = AMOVL;
   980  		}
   981  		break;
   982  
   983  	case CASE(	TCHAR,	TVLONG):
   984  	case CASE(	TCHAR,	TUVLONG):
   985  	case CASE(	TCHAR,	TIND):
   986  		a = AMOVBQSX;
   987  		if(f->op == OCONST) {
   988  			f->vconst &= 0xff;
   989  			if(f->vconst & 0x80){
   990  				f->vconst |= 0xffffff00;
   991  				f->vconst |= (vlong)~0 << 32;
   992  			}
   993  			a = AMOVQ;
   994  		}
   995  		break;
   996  
   997  	case CASE(	TUCHAR,	TSHORT):
   998  	case CASE(	TUCHAR,	TUSHORT):
   999  	case CASE(	TUCHAR,	TINT):
  1000  	case CASE(	TUCHAR,	TUINT):
  1001  	case CASE(	TUCHAR,	TLONG):
  1002  	case CASE(	TUCHAR,	TULONG):
  1003  		a = AMOVBLZX;
  1004  		if(f->op == OCONST) {
  1005  			f->vconst &= 0xff;
  1006  			a = AMOVL;
  1007  		}
  1008  		break;
  1009  
  1010  	case CASE(	TUCHAR,	TVLONG):
  1011  	case CASE(	TUCHAR,	TUVLONG):
  1012  	case CASE(	TUCHAR,	TIND):
  1013  		a = AMOVBQZX;
  1014  		if(f->op == OCONST) {
  1015  			f->vconst &= 0xff;
  1016  			a = AMOVL;	/* zero-extends to 64-bits */
  1017  		}
  1018  		break;
  1019  
  1020  /*
  1021   * float to fix
  1022   */
  1023  	case CASE(	TFLOAT,	TCHAR):
  1024  	case CASE(	TFLOAT,	TUCHAR):
  1025  	case CASE(	TFLOAT,	TSHORT):
  1026  	case CASE(	TFLOAT,	TUSHORT):
  1027  	case CASE(	TFLOAT,	TINT):
  1028  	case CASE(	TFLOAT,	TUINT):
  1029  	case CASE(	TFLOAT,	TLONG):
  1030  	case CASE(	TFLOAT,	TULONG):
  1031  	case CASE(	TFLOAT,	TVLONG):
  1032  	case CASE(	TFLOAT,	TUVLONG):
  1033  	case CASE(	TFLOAT,	TIND):
  1034  
  1035  	case CASE(	TDOUBLE,TCHAR):
  1036  	case CASE(	TDOUBLE,TUCHAR):
  1037  	case CASE(	TDOUBLE,TSHORT):
  1038  	case CASE(	TDOUBLE,TUSHORT):
  1039  	case CASE(	TDOUBLE,TINT):
  1040  	case CASE(	TDOUBLE,TUINT):
  1041  	case CASE(	TDOUBLE,TLONG):
  1042  	case CASE(	TDOUBLE,TULONG):
  1043  	case CASE(	TDOUBLE,TVLONG):
  1044  	case CASE(	TDOUBLE,TUVLONG):
  1045  	case CASE(	TDOUBLE,TIND):
  1046  		regalloc(&nod, t, Z);
  1047  		if(ewidth[tt] == SZ_VLONG || typeu[tt] && ewidth[tt] == SZ_INT){
  1048  			if(ft == TFLOAT)
  1049  				a = ACVTTSS2SQ;
  1050  			else
  1051  				a = ACVTTSD2SQ;
  1052  		}else{
  1053  			if(ft == TFLOAT)
  1054  				a = ACVTTSS2SL;
  1055  			else
  1056  				a = ACVTTSD2SL;
  1057  		}
  1058  		gins(a, f, &nod);
  1059  		gmove(&nod, t);
  1060  		regfree(&nod);
  1061  		return;
  1062  
  1063  /*
  1064   * uvlong to float
  1065   */
  1066  	case CASE(	TUVLONG,	TDOUBLE):
  1067  	case CASE(	TUVLONG,	TFLOAT):
  1068  		a = ACVTSQ2SS;
  1069  		if(tt == TDOUBLE)
  1070  			a = ACVTSQ2SD;
  1071  		regalloc(&nod, f, f);
  1072  		gmove(f, &nod);
  1073  		regalloc(&nod1, t, t);
  1074  		gins(ACMPQ, &nod, nodconst(0));
  1075  		gins(AJLT, Z, Z);
  1076  		p1 = p;
  1077  		gins(a, &nod, &nod1);
  1078  		gins(AJMP, Z, Z);
  1079  		p2 = p;
  1080  		patch(p1, pc);
  1081  		regalloc(&nod2, f, Z);
  1082  		regalloc(&nod3, f, Z);
  1083  		gmove(&nod, &nod2);
  1084  		gins(ASHRQ, nodconst(1), &nod2);
  1085  		gmove(&nod, &nod3);
  1086  		gins(AANDL, nodconst(1), &nod3);
  1087  		gins(AORQ, &nod3, &nod2);
  1088  		gins(a, &nod2, &nod1);
  1089  		gins(tt == TDOUBLE? AADDSD: AADDSS, &nod1, &nod1);
  1090  		regfree(&nod2);
  1091  		regfree(&nod3);
  1092  		patch(p2, pc);
  1093  		regfree(&nod);
  1094  		regfree(&nod1);
  1095  		return;
  1096  
  1097  	case CASE(	TULONG,	TDOUBLE):
  1098  	case CASE(	TUINT,	TDOUBLE):
  1099  	case CASE(	TULONG,	TFLOAT):
  1100  	case CASE(	TUINT,	TFLOAT):
  1101  		a = ACVTSQ2SS;
  1102  		if(tt == TDOUBLE)
  1103  			a = ACVTSQ2SD;
  1104  		regalloc(&nod, f, f);
  1105  		gins(AMOVLQZX, f, &nod);
  1106  		regalloc(&nod1, t, t);
  1107  		gins(a, &nod, &nod1);
  1108  		gmove(&nod1, t);
  1109  		regfree(&nod);
  1110  		regfree(&nod1);
  1111  		return;
  1112  
  1113  /*
  1114   * fix to float
  1115   */
  1116  	case CASE(	TCHAR,	TFLOAT):
  1117  	case CASE(	TUCHAR,	TFLOAT):
  1118  	case CASE(	TSHORT,	TFLOAT):
  1119  	case CASE(	TUSHORT,TFLOAT):
  1120  	case CASE(	TINT,	TFLOAT):
  1121  	case CASE(	TLONG,	TFLOAT):
  1122  	case	CASE(	TVLONG,	TFLOAT):
  1123  	case CASE(	TIND,	TFLOAT):
  1124  
  1125  	case CASE(	TCHAR,	TDOUBLE):
  1126  	case CASE(	TUCHAR,	TDOUBLE):
  1127  	case CASE(	TSHORT,	TDOUBLE):
  1128  	case CASE(	TUSHORT,TDOUBLE):
  1129  	case CASE(	TINT,	TDOUBLE):
  1130  	case CASE(	TLONG,	TDOUBLE):
  1131  	case CASE(	TVLONG,	TDOUBLE):
  1132  	case CASE(	TIND,	TDOUBLE):
  1133  		regalloc(&nod, t, t);
  1134  		if(ewidth[ft] == SZ_VLONG){
  1135  			if(tt == TFLOAT)
  1136  				a = ACVTSQ2SS;
  1137  			else
  1138  				a = ACVTSQ2SD;
  1139  		}else{
  1140  			if(tt == TFLOAT)
  1141  				a = ACVTSL2SS;
  1142  			else
  1143  				a = ACVTSL2SD;
  1144  		}
  1145  		gins(a, f, &nod);
  1146  		gmove(&nod, t);
  1147  		regfree(&nod);
  1148  		return;
  1149  
  1150  /*
  1151   * float to float
  1152   */
  1153  	case CASE(	TFLOAT,	TFLOAT):
  1154  		a = AMOVSS;
  1155  		break;
  1156  	case CASE(	TDOUBLE,TFLOAT):
  1157  		a = ACVTSD2SS;
  1158  		break;
  1159  	case CASE(	TFLOAT,	TDOUBLE):
  1160  		a = ACVTSS2SD;
  1161  		break;
  1162  	case CASE(	TDOUBLE,TDOUBLE):
  1163  		a = AMOVSD;
  1164  		break;
  1165  	}
  1166  	if(a == AMOVQ || a == AMOVSD || a == AMOVSS || a == AMOVL && ewidth[ft] == ewidth[tt])	/* TO DO: check AMOVL */
  1167  	if(samaddr(f, t))
  1168  		return;
  1169  	gins(a, f, t);
  1170  }
  1171  
  1172  void
  1173  doindex(Node *n)
  1174  {
  1175  	Node nod, nod1;
  1176  	int32 v;
  1177  
  1178  if(debug['Y'])
  1179  prtree(n, "index");
  1180  
  1181  if(n->left->complex >= FNX)
  1182  print("botch in doindex\n");
  1183  
  1184  	regalloc(&nod, &qregnode, Z);
  1185  	v = constnode.vconst;
  1186  	cgen(n->right, &nod);
  1187  	idx.ptr = D_NONE;
  1188  	if(n->left->op == OCONST)
  1189  		idx.ptr = D_CONST;
  1190  	else if(n->left->op == OREGISTER)
  1191  		idx.ptr = n->left->reg;
  1192  	else if(n->left->op != OADDR) {
  1193  		reg[D_BP]++;	// cant be used as a base
  1194  		regalloc(&nod1, &qregnode, Z);
  1195  		cgen(n->left, &nod1);
  1196  		idx.ptr = nod1.reg;
  1197  		regfree(&nod1);
  1198  		reg[D_BP]--;
  1199  	}
  1200  	idx.reg = nod.reg;
  1201  	regfree(&nod);
  1202  	constnode.vconst = v;
  1203  }
  1204  
  1205  void
  1206  gins(int a, Node *f, Node *t)
  1207  {
  1208  
  1209  	if(f != Z && f->op == OINDEX)
  1210  		doindex(f);
  1211  	if(t != Z && t->op == OINDEX)
  1212  		doindex(t);
  1213  	nextpc();
  1214  	p->as = a;
  1215  	if(f != Z)
  1216  		naddr(f, &p->from);
  1217  	if(t != Z)
  1218  		naddr(t, &p->to);
  1219  	if(debug['g'])
  1220  		print("%P\n", p);
  1221  }
  1222  
  1223  void
  1224  gopcode(int o, Type *ty, Node *f, Node *t)
  1225  {
  1226  	int a, et;
  1227  
  1228  	et = TLONG;
  1229  	if(ty != T)
  1230  		et = ty->etype;
  1231  	if(debug['M']) {
  1232  		if(f != Z && f->type != T)
  1233  			print("gop: %O %O[%s],", o, f->op, tnames[et]);
  1234  		else
  1235  			print("gop: %O Z,", o);
  1236  		if(t != Z && t->type != T)
  1237  			print("%O[%s]\n", t->op, tnames[t->type->etype]);
  1238  		else
  1239  			print("Z\n");
  1240  	}
  1241  	a = AGOK;
  1242  	switch(o) {
  1243  	case OCOM:
  1244  		a = ANOTL;
  1245  		if(et == TCHAR || et == TUCHAR)
  1246  			a = ANOTB;
  1247  		if(et == TSHORT || et == TUSHORT)
  1248  			a = ANOTW;
  1249  		if(et == TVLONG || et == TUVLONG || et == TIND)
  1250  			a = ANOTQ;
  1251  		break;
  1252  
  1253  	case ONEG:
  1254  		a = ANEGL;
  1255  		if(et == TCHAR || et == TUCHAR)
  1256  			a = ANEGB;
  1257  		if(et == TSHORT || et == TUSHORT)
  1258  			a = ANEGW;
  1259  		if(et == TVLONG || et == TUVLONG || et == TIND)
  1260  			a = ANEGQ;
  1261  		break;
  1262  
  1263  	case OADDR:
  1264  		a = ALEAQ;
  1265  		break;
  1266  
  1267  	case OASADD:
  1268  	case OADD:
  1269  		a = AADDL;
  1270  		if(et == TCHAR || et == TUCHAR)
  1271  			a = AADDB;
  1272  		if(et == TSHORT || et == TUSHORT)
  1273  			a = AADDW;
  1274  		if(et == TVLONG || et == TUVLONG || et == TIND)
  1275  			a = AADDQ;
  1276  		if(et == TFLOAT)
  1277  			a = AADDSS;
  1278  		if(et == TDOUBLE)
  1279  			a = AADDSD;
  1280  		break;
  1281  
  1282  	case OASSUB:
  1283  	case OSUB:
  1284  		a = ASUBL;
  1285  		if(et == TCHAR || et == TUCHAR)
  1286  			a = ASUBB;
  1287  		if(et == TSHORT || et == TUSHORT)
  1288  			a = ASUBW;
  1289  		if(et == TVLONG || et == TUVLONG || et == TIND)
  1290  			a = ASUBQ;
  1291  		if(et == TFLOAT)
  1292  			a = ASUBSS;
  1293  		if(et == TDOUBLE)
  1294  			a = ASUBSD;
  1295  		break;
  1296  
  1297  	case OASOR:
  1298  	case OOR:
  1299  		a = AORL;
  1300  		if(et == TCHAR || et == TUCHAR)
  1301  			a = AORB;
  1302  		if(et == TSHORT || et == TUSHORT)
  1303  			a = AORW;
  1304  		if(et == TVLONG || et == TUVLONG || et == TIND)
  1305  			a = AORQ;
  1306  		break;
  1307  
  1308  	case OASAND:
  1309  	case OAND:
  1310  		a = AANDL;
  1311  		if(et == TCHAR || et == TUCHAR)
  1312  			a = AANDB;
  1313  		if(et == TSHORT || et == TUSHORT)
  1314  			a = AANDW;
  1315  		if(et == TVLONG || et == TUVLONG || et == TIND)
  1316  			a = AANDQ;
  1317  		break;
  1318  
  1319  	case OASXOR:
  1320  	case OXOR:
  1321  		a = AXORL;
  1322  		if(et == TCHAR || et == TUCHAR)
  1323  			a = AXORB;
  1324  		if(et == TSHORT || et == TUSHORT)
  1325  			a = AXORW;
  1326  		if(et == TVLONG || et == TUVLONG || et == TIND)
  1327  			a = AXORQ;
  1328  		break;
  1329  
  1330  	case OASLSHR:
  1331  	case OLSHR:
  1332  		a = ASHRL;
  1333  		if(et == TCHAR || et == TUCHAR)
  1334  			a = ASHRB;
  1335  		if(et == TSHORT || et == TUSHORT)
  1336  			a = ASHRW;
  1337  		if(et == TVLONG || et == TUVLONG || et == TIND)
  1338  			a = ASHRQ;
  1339  		break;
  1340  
  1341  	case OASASHR:
  1342  	case OASHR:
  1343  		a = ASARL;
  1344  		if(et == TCHAR || et == TUCHAR)
  1345  			a = ASARB;
  1346  		if(et == TSHORT || et == TUSHORT)
  1347  			a = ASARW;
  1348  		if(et == TVLONG || et == TUVLONG || et == TIND)
  1349  			a = ASARQ;
  1350  		break;
  1351  
  1352  	case OASASHL:
  1353  	case OASHL:
  1354  		a = ASALL;
  1355  		if(et == TCHAR || et == TUCHAR)
  1356  			a = ASALB;
  1357  		if(et == TSHORT || et == TUSHORT)
  1358  			a = ASALW;
  1359  		if(et == TVLONG || et == TUVLONG || et == TIND)
  1360  			a = ASALQ;
  1361  		break;
  1362  
  1363  	case OROTL:
  1364  		a = AROLL;
  1365  		if(et == TCHAR || et == TUCHAR)
  1366  			a = AROLB;
  1367  		if(et == TSHORT || et == TUSHORT)
  1368  			a = AROLW;
  1369  		if(et == TVLONG || et == TUVLONG || et == TIND)
  1370  			a = AROLQ;
  1371  		break;
  1372  
  1373  	case OFUNC:
  1374  		a = ACALL;
  1375  		break;
  1376  
  1377  	case OASMUL:
  1378  	case OMUL:
  1379  		if(f->op == OREGISTER && t != Z && isreg(t, D_AX) && reg[D_DX] == 0)
  1380  			t = Z;
  1381  		a = AIMULL;
  1382  		if(et == TVLONG || et == TUVLONG || et == TIND)
  1383  			a = AIMULQ;
  1384  		if(et == TFLOAT)
  1385  			a = AMULSS;
  1386  		if(et == TDOUBLE)
  1387  			a = AMULSD;
  1388  		break;
  1389  
  1390  	case OASMOD:
  1391  	case OMOD:
  1392  	case OASDIV:
  1393  	case ODIV:
  1394  		a = AIDIVL;
  1395  		if(et == TVLONG || et == TUVLONG || et == TIND)
  1396  			a = AIDIVQ;
  1397  		if(et == TFLOAT)
  1398  			a = ADIVSS;
  1399  		if(et == TDOUBLE)
  1400  			a = ADIVSD;
  1401  		break;
  1402  
  1403  	case OASLMUL:
  1404  	case OLMUL:
  1405  		a = AMULL;
  1406  		if(et == TVLONG || et == TUVLONG || et == TIND)
  1407  			a = AMULQ;
  1408  		break;
  1409  
  1410  	case OASLMOD:
  1411  	case OLMOD:
  1412  	case OASLDIV:
  1413  	case OLDIV:
  1414  		a = ADIVL;
  1415  		if(et == TVLONG || et == TUVLONG || et == TIND)
  1416  			a = ADIVQ;
  1417  		break;
  1418  
  1419  	case OEQ:
  1420  	case ONE:
  1421  	case OLT:
  1422  	case OLE:
  1423  	case OGE:
  1424  	case OGT:
  1425  	case OLO:
  1426  	case OLS:
  1427  	case OHS:
  1428  	case OHI:
  1429  		a = ACMPL;
  1430  		if(et == TCHAR || et == TUCHAR)
  1431  			a = ACMPB;
  1432  		if(et == TSHORT || et == TUSHORT)
  1433  			a = ACMPW;
  1434  		if(et == TVLONG || et == TUVLONG || et == TIND)
  1435  			a = ACMPQ;
  1436  		if(et == TFLOAT)
  1437  			a = AUCOMISS;
  1438  		if(et == TDOUBLE)
  1439  			a = AUCOMISD;
  1440  		gins(a, f, t);
  1441  		switch(o) {
  1442  		case OEQ:	a = AJEQ; break;
  1443  		case ONE:	a = AJNE; break;
  1444  		case OLT:	a = AJLT; break;
  1445  		case OLE:	a = AJLE; break;
  1446  		case OGE:	a = AJGE; break;
  1447  		case OGT:	a = AJGT; break;
  1448  		case OLO:	a = AJCS; break;
  1449  		case OLS:	a = AJLS; break;
  1450  		case OHS:	a = AJCC; break;
  1451  		case OHI:	a = AJHI; break;
  1452  		}
  1453  		gins(a, Z, Z);
  1454  		return;
  1455  	}
  1456  	if(a == AGOK)
  1457  		diag(Z, "bad in gopcode %O", o);
  1458  	gins(a, f, t);
  1459  }
  1460  
  1461  int
  1462  samaddr(Node *f, Node *t)
  1463  {
  1464  	return f->op == OREGISTER && t->op == OREGISTER && f->reg == t->reg;
  1465  }
  1466  
  1467  void
  1468  gbranch(int o)
  1469  {
  1470  	int a;
  1471  
  1472  	a = AGOK;
  1473  	switch(o) {
  1474  	case ORETURN:
  1475  		a = ARET;
  1476  		break;
  1477  	case OGOTO:
  1478  		a = AJMP;
  1479  		break;
  1480  	}
  1481  	nextpc();
  1482  	if(a == AGOK) {
  1483  		diag(Z, "bad in gbranch %O",  o);
  1484  		nextpc();
  1485  	}
  1486  	p->as = a;
  1487  }
  1488  
  1489  void
  1490  patch(Prog *op, int32 pc)
  1491  {
  1492  
  1493  	op->to.offset = pc;
  1494  	op->to.type = D_BRANCH;
  1495  }
  1496  
  1497  void
  1498  gpseudo(int a, Sym *s, Node *n)
  1499  {
  1500  
  1501  	nextpc();
  1502  	p->as = a;
  1503  	p->from.type = D_EXTERN;
  1504  	p->from.sym = s;
  1505  	p->from.scale = textflag;
  1506  	textflag = 0;
  1507  
  1508  	if(s->class == CSTATIC)
  1509  		p->from.type = D_STATIC;
  1510  	naddr(n, &p->to);
  1511  	if(a == ADATA || a == AGLOBL)
  1512  		pc--;
  1513  }
  1514  
  1515  void
  1516  gprefetch(Node *n)
  1517  {
  1518  	Node n1;
  1519  	
  1520  	regalloc(&n1, n, Z);
  1521  	gmove(n, &n1);
  1522  	n1.op = OINDREG;
  1523  	gins(APREFETCHNTA, &n1, Z);
  1524  	regfree(&n1);
  1525  }
  1526  
  1527  int
  1528  sconst(Node *n)
  1529  {
  1530  	int32 v;
  1531  
  1532  	if(n->op == OCONST && !typefd[n->type->etype]) {
  1533  		v = n->vconst;
  1534  		if(v >= -32766L && v < 32766L)
  1535  			return 1;
  1536  	}
  1537  	return 0;
  1538  }
  1539  
  1540  int32
  1541  exreg(Type *t)
  1542  {
  1543  	int32 o;
  1544  
  1545  	if(typechlpv[t->etype]) {
  1546  		if(exregoffset >= 64)
  1547  			return 0;
  1548  		o = exregoffset;
  1549  		exregoffset += 8;
  1550  		return o+1;	// +1 to avoid 0 == failure; naddr's case OEXREG will subtract 1.
  1551  	}
  1552  	return 0;
  1553  }
  1554  
  1555  schar	ewidth[NTYPE] =
  1556  {
  1557  	-1,		/*[TXXX]*/
  1558  	SZ_CHAR,	/*[TCHAR]*/
  1559  	SZ_CHAR,	/*[TUCHAR]*/
  1560  	SZ_SHORT,	/*[TSHORT]*/
  1561  	SZ_SHORT,	/*[TUSHORT]*/
  1562  	SZ_INT,		/*[TINT]*/
  1563  	SZ_INT,		/*[TUINT]*/
  1564  	SZ_LONG,	/*[TLONG]*/
  1565  	SZ_LONG,	/*[TULONG]*/
  1566  	SZ_VLONG,	/*[TVLONG]*/
  1567  	SZ_VLONG,	/*[TUVLONG]*/
  1568  	SZ_FLOAT,	/*[TFLOAT]*/
  1569  	SZ_DOUBLE,	/*[TDOUBLE]*/
  1570  	SZ_IND,		/*[TIND]*/
  1571  	0,		/*[TFUNC]*/
  1572  	-1,		/*[TARRAY]*/
  1573  	0,		/*[TVOID]*/
  1574  	-1,		/*[TSTRUCT]*/
  1575  	-1,		/*[TUNION]*/
  1576  	SZ_INT,		/*[TENUM]*/
  1577  };
  1578  int32	ncast[NTYPE] =
  1579  {
  1580  	0,				/*[TXXX]*/
  1581  	BCHAR|BUCHAR,			/*[TCHAR]*/
  1582  	BCHAR|BUCHAR,			/*[TUCHAR]*/
  1583  	BSHORT|BUSHORT,			/*[TSHORT]*/
  1584  	BSHORT|BUSHORT,			/*[TUSHORT]*/
  1585  	BINT|BUINT|BLONG|BULONG,	/*[TINT]*/
  1586  	BINT|BUINT|BLONG|BULONG,	/*[TUINT]*/
  1587  	BINT|BUINT|BLONG|BULONG,	/*[TLONG]*/
  1588  	BINT|BUINT|BLONG|BULONG,	/*[TULONG]*/
  1589  	BVLONG|BUVLONG|BIND,			/*[TVLONG]*/
  1590  	BVLONG|BUVLONG|BIND,			/*[TUVLONG]*/
  1591  	BFLOAT,				/*[TFLOAT]*/
  1592  	BDOUBLE,			/*[TDOUBLE]*/
  1593  	BVLONG|BUVLONG|BIND,		/*[TIND]*/
  1594  	0,				/*[TFUNC]*/
  1595  	0,				/*[TARRAY]*/
  1596  	0,				/*[TVOID]*/
  1597  	BSTRUCT,			/*[TSTRUCT]*/
  1598  	BUNION,				/*[TUNION]*/
  1599  	0,				/*[TENUM]*/
  1600  };