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