github.com/akaros/go-akaros@v0.0.0-20181004170632-85005d477eab/src/cmd/8c/cgen64.c (about)

     1  // Inferno utils/8c/cgen64.c
     2  // http://code.google.com/p/inferno-os/source/browse/utils/8c/cgen64.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  zeroregm(Node *n)
    35  {
    36  	gins(AMOVL, nodconst(0), n);
    37  }
    38  
    39  /* do we need to load the address of a vlong? */
    40  int
    41  vaddr(Node *n, int a)
    42  {
    43  	switch(n->op) {
    44  	case ONAME:
    45  		if(a)
    46  			return 1;
    47  		return !(n->class == CEXTERN || n->class == CGLOBL || n->class == CSTATIC);
    48  
    49  	case OCONST:
    50  	case OREGISTER:
    51  	case OINDREG:
    52  		return 1;
    53  	}
    54  	return 0;
    55  }
    56  
    57  int32
    58  hi64v(Node *n)
    59  {
    60  	if(align(0, types[TCHAR], Aarg1, nil))	/* isbigendian */
    61  		return (int32)(n->vconst) & ~0L;
    62  	else
    63  		return (int32)((uvlong)n->vconst>>32) & ~0L;
    64  }
    65  
    66  int32
    67  lo64v(Node *n)
    68  {
    69  	if(align(0, types[TCHAR], Aarg1, nil))	/* isbigendian */
    70  		return (int32)((uvlong)n->vconst>>32) & ~0L;
    71  	else
    72  		return (int32)(n->vconst) & ~0L;
    73  }
    74  
    75  Node *
    76  hi64(Node *n)
    77  {
    78  	return nodconst(hi64v(n));
    79  }
    80  
    81  Node *
    82  lo64(Node *n)
    83  {
    84  	return nodconst(lo64v(n));
    85  }
    86  
    87  static Node *
    88  anonreg(void)
    89  {
    90  	Node *n;
    91  
    92  	n = new(OREGISTER, Z, Z);
    93  	n->reg = D_NONE;
    94  	n->type = types[TLONG];
    95  	return n;
    96  }
    97  
    98  static Node *
    99  regpair(Node *n, Node *t)
   100  {
   101  	Node *r;
   102  
   103  	if(n != Z && n->op == OREGPAIR)
   104  		return n;
   105  	r = new(OREGPAIR, anonreg(), anonreg());
   106  	if(n != Z)
   107  		r->type = n->type;
   108  	else
   109  		r->type = t->type;
   110  	return r;
   111  }
   112  
   113  static void
   114  evacaxdx(Node *r)
   115  {
   116  	Node nod1, nod2;
   117  
   118  	if(r->reg == D_AX || r->reg == D_DX) {
   119  		reg[D_AX]++;
   120  		reg[D_DX]++;
   121  		/*
   122  		 * this is just an optim that should
   123  		 * check for spill
   124  		 */
   125  		r->type = types[TULONG];
   126  		regalloc(&nod1, r, Z);
   127  		nodreg(&nod2, Z, r->reg);
   128  		gins(AMOVL, &nod2, &nod1);
   129  		regfree(r);
   130  		r->reg = nod1.reg;
   131  		reg[D_AX]--;
   132  		reg[D_DX]--;
   133  	}
   134  }
   135  
   136  /* lazy instantiation of register pair */
   137  static int
   138  instpair(Node *n, Node *l)
   139  {
   140  	int r;
   141  
   142  	r = 0;
   143  	if(n->left->reg == D_NONE) {
   144  		if(l != Z) {
   145  			n->left->reg = l->reg;
   146  			r = 1;
   147  		}
   148  		else
   149  			regalloc(n->left, n->left, Z);
   150  	}
   151  	if(n->right->reg == D_NONE)
   152  		regalloc(n->right, n->right, Z);
   153  	return r;
   154  }
   155  
   156  static void
   157  zapreg(Node *n)
   158  {
   159  	if(n->reg != D_NONE) {
   160  		regfree(n);
   161  		n->reg = D_NONE;
   162  	}
   163  }
   164  
   165  static void
   166  freepair(Node *n)
   167  {
   168  	regfree(n->left);
   169  	regfree(n->right);
   170  }
   171  
   172  /* n is not OREGPAIR, nn is */
   173  void
   174  loadpair(Node *n, Node *nn)
   175  {
   176  	Node nod;
   177  
   178  	instpair(nn, Z);
   179  	if(n->op == OCONST) {
   180  		gins(AMOVL, lo64(n), nn->left);
   181  		n->xoffset += SZ_LONG;
   182  		gins(AMOVL, hi64(n), nn->right);
   183  		n->xoffset -= SZ_LONG;
   184  		return;
   185  	}
   186  	if(!vaddr(n, 0)) {
   187  		/* steal the right register for the laddr */
   188  		nod = regnode;
   189  		nod.reg = nn->right->reg;
   190  		lcgen(n, &nod);
   191  		n = &nod;
   192  		regind(n, n);
   193  		n->xoffset = 0;
   194  	}
   195  	gins(AMOVL, n, nn->left);
   196  	n->xoffset += SZ_LONG;
   197  	gins(AMOVL, n, nn->right);
   198  	n->xoffset -= SZ_LONG;
   199  }
   200  
   201  /* n is OREGPAIR, nn is not */
   202  static void
   203  storepair(Node *n, Node *nn, int f)
   204  {
   205  	Node nod;
   206  
   207  	if(!vaddr(nn, 0)) {
   208  		reglcgen(&nod, nn, Z);
   209  		nn = &nod;
   210  	}
   211  	gins(AMOVL, n->left, nn);
   212  	nn->xoffset += SZ_LONG;
   213  	gins(AMOVL, n->right, nn);
   214  	nn->xoffset -= SZ_LONG;
   215  	if(nn == &nod)
   216  		regfree(&nod);
   217  	if(f)
   218  		freepair(n);
   219  }
   220  
   221  enum
   222  {
   223  /* 4 only, see WW */
   224  	WNONE	= 0,
   225  	WCONST,
   226  	WADDR,
   227  	WHARD,
   228  };
   229  
   230  static int
   231  whatof(Node *n, int a)
   232  {
   233  	if(n->op == OCONST)
   234  		return WCONST;
   235  	return !vaddr(n, a) ? WHARD : WADDR;
   236  }
   237  
   238  /* can upgrade an extern to addr for AND */
   239  static int
   240  reduxv(Node *n)
   241  {
   242  	return lo64v(n) == 0 || hi64v(n) == 0;
   243  }
   244  
   245  int
   246  cond(int op)
   247  {
   248  	switch(op) {
   249  	case OANDAND:
   250  	case OOROR:
   251  	case ONOT:
   252  		return 1;
   253  
   254  	case OEQ:
   255  	case ONE:
   256  	case OLE:
   257  	case OLT:
   258  	case OGE:
   259  	case OGT:
   260  	case OHI:
   261  	case OHS:
   262  	case OLO:
   263  	case OLS:
   264  		return 1;
   265  	}
   266  	return 0;
   267  }
   268  
   269  /*
   270   * for a func operand call it and then return
   271   * the safe node
   272   */
   273  static Node *
   274  vfunc(Node *n, Node *nn)
   275  {
   276  	Node *t;
   277  
   278  	if(n->op != OFUNC)
   279  		return n;
   280  	t = new(0, Z, Z);
   281  	if(nn == Z || nn == nodret)
   282  		nn = n;
   283  	regsalloc(t, nn);
   284  	sugen(n, t, 8);
   285  	return t;
   286  }
   287  
   288  /* try to steal a reg */
   289  static int
   290  getreg(Node **np, Node *t, int r)
   291  {
   292  	Node *n, *p;
   293  
   294  	n = *np;
   295  	if(n->reg == r) {
   296  		p = new(0, Z, Z);
   297  		regalloc(p, n, Z);
   298  		gins(AMOVL, n, p);
   299  		*t = *n;
   300  		*np = p;
   301  		return 1;
   302  	}
   303  	return 0;
   304  }
   305  
   306  static Node *
   307  snarfreg(Node *n, Node *t, int r, Node *d, Node *c)
   308  {
   309  	if(n == Z || n->op != OREGPAIR || (!getreg(&n->left, t, r) && !getreg(&n->right, t, r))) {
   310  		if(nodreg(t, Z, r)) {
   311  			regalloc(c, d, Z);
   312  			gins(AMOVL, t, c);
   313  			reg[r]++;
   314  			return c;
   315  		}
   316  		reg[r]++;
   317  	}
   318  	return Z;
   319  }
   320  
   321  enum
   322  {
   323  	Vstart	= OEND,
   324  
   325  	Vgo,
   326  	Vamv,
   327  	Vmv,
   328  	Vzero,
   329  	Vop,
   330  	Vopx,
   331  	Vins,
   332  	Vins0,
   333  	Vinsl,
   334  	Vinsr,
   335  	Vinsla,
   336  	Vinsra,
   337  	Vinsx,
   338  	Vmul,
   339  	Vshll,
   340  	VT,
   341  	VF,
   342  	V_l_lo_f,
   343  	V_l_hi_f,
   344  	V_l_lo_t,
   345  	V_l_hi_t,
   346  	V_l_lo_u,
   347  	V_l_hi_u,
   348  	V_r_lo_f,
   349  	V_r_hi_f,
   350  	V_r_lo_t,
   351  	V_r_hi_t,
   352  	V_r_lo_u,
   353  	V_r_hi_u,
   354  	Vspazz,
   355  	Vend,
   356  
   357  	V_T0,
   358  	V_T1,
   359  	V_F0,
   360  	V_F1,
   361  
   362  	V_a0,
   363  	V_a1,
   364  	V_f0,
   365  	V_f1,
   366  
   367  	V_p0,
   368  	V_p1,
   369  	V_p2,
   370  	V_p3,
   371  	V_p4,
   372  
   373  	V_s0,
   374  	V_s1,
   375  	V_s2,
   376  	V_s3,
   377  	V_s4,
   378  
   379  	C00,
   380  	C01,
   381  	C31,
   382  	C32,
   383  
   384  	O_l_lo,
   385  	O_l_hi,
   386  	O_r_lo,
   387  	O_r_hi,
   388  	O_t_lo,
   389  	O_t_hi,
   390  	O_l,
   391  	O_r,
   392  	O_l_rp,
   393  	O_r_rp,
   394  	O_t_rp,
   395  	O_r0,
   396  	O_r1,
   397  	O_Zop,
   398  
   399  	O_a0,
   400  	O_a1,
   401  
   402  	V_C0,
   403  	V_C1,
   404  
   405  	V_S0,
   406  	V_S1,
   407  
   408  	VOPS	= 5,
   409  	VLEN	= 5,
   410  	VARGS	= 2,
   411  
   412  	S00	= 0,
   413  	Sc0,
   414  	Sc1,
   415  	Sc2,
   416  	Sac3,
   417  	Sac4,
   418  	S10,
   419  
   420  	SAgen	= 0,
   421  	SAclo,
   422  	SAc32,
   423  	SAchi,
   424  	SAdgen,
   425  	SAdclo,
   426  	SAdc32,
   427  	SAdchi,
   428  
   429  	B0c	= 0,
   430  	Bca,
   431  	Bac,
   432  
   433  	T0i	= 0,
   434  	Tii,
   435  
   436  	Bop0	= 0,
   437  	Bop1,
   438  };
   439  
   440  /*
   441   * _testv:
   442   * 	CMPL	lo,$0
   443   * 	JNE	true
   444   * 	CMPL	hi,$0
   445   * 	JNE	true
   446   * 	GOTO	false
   447   * false:
   448   * 	GOTO	code
   449   * true:
   450   * 	GOTO	patchme
   451   * code:
   452   */
   453  
   454  static uchar	testi[][VLEN] =
   455  {
   456  	{Vop, ONE, O_l_lo, C00},
   457  	{V_s0, Vop, ONE, O_l_hi, C00},
   458  	{V_s1, Vgo, V_s2, Vgo, V_s3},
   459  	{VF, V_p0, V_p1, VT, V_p2},
   460  	{Vgo, V_p3},
   461  	{VT, V_p0, V_p1, VF, V_p2},
   462  	{Vend},
   463  };
   464  
   465  /* shift left general case */
   466  static uchar	shll00[][VLEN] =
   467  {
   468  	{Vop, OGE, O_r, C32},
   469  	{V_s0, Vinsl, ASHLL, O_r, O_l_rp},
   470  	{Vins, ASHLL, O_r, O_l_lo, Vgo},
   471  	{V_p0, V_s0},
   472  	{Vins, ASHLL, O_r, O_l_lo},
   473  	{Vins, AMOVL, O_l_lo, O_l_hi},
   474  	{Vzero, O_l_lo, V_p0, Vend},
   475  };
   476  
   477  /* shift left rp, const < 32 */
   478  static uchar	shllc0[][VLEN] =
   479  {
   480  	{Vinsl, ASHLL, O_r, O_l_rp},
   481  	{Vshll, O_r, O_l_lo, Vend},
   482  };
   483  
   484  /* shift left rp, const == 32 */
   485  static uchar	shllc1[][VLEN] =
   486  {
   487  	{Vins, AMOVL, O_l_lo, O_l_hi},
   488  	{Vzero, O_l_lo, Vend},
   489  };
   490  
   491  /* shift left rp, const > 32 */
   492  static uchar	shllc2[][VLEN] =
   493  {
   494  	{Vshll, O_r, O_l_lo},
   495  	{Vins, AMOVL, O_l_lo, O_l_hi},
   496  	{Vzero, O_l_lo, Vend},
   497  };
   498  
   499  /* shift left addr, const == 32 */
   500  static uchar	shllac3[][VLEN] =
   501  {
   502  	{Vins, AMOVL, O_l_lo, O_t_hi},
   503  	{Vzero, O_t_lo, Vend},
   504  };
   505  
   506  /* shift left addr, const > 32 */
   507  static uchar	shllac4[][VLEN] =
   508  {
   509  	{Vins, AMOVL, O_l_lo, O_t_hi},
   510  	{Vshll, O_r, O_t_hi},
   511  	{Vzero, O_t_lo, Vend},
   512  };
   513  
   514  /* shift left of constant */
   515  static uchar	shll10[][VLEN] =
   516  {
   517  	{Vop, OGE, O_r, C32},
   518  	{V_s0, Vins, AMOVL, O_l_lo, O_t_lo},
   519  	{Vins, AMOVL, O_l_hi, O_t_hi},
   520  	{Vinsl, ASHLL, O_r, O_t_rp},
   521  	{Vins, ASHLL, O_r, O_t_lo, Vgo},
   522  	{V_p0, V_s0},
   523  	{Vins, AMOVL, O_l_lo, O_t_hi},
   524  	{V_l_lo_t, Vins, ASHLL, O_r, O_t_hi},
   525  	{Vzero, O_t_lo, V_p0, Vend},
   526  };
   527  
   528  static uchar	(*shlltab[])[VLEN] =
   529  {
   530  	shll00,
   531  	shllc0,
   532  	shllc1,
   533  	shllc2,
   534  	shllac3,
   535  	shllac4,
   536  	shll10,
   537  };
   538  
   539  /* shift right general case */
   540  static uchar	shrl00[][VLEN] =
   541  {
   542  	{Vop, OGE, O_r, C32},
   543  	{V_s0, Vinsr, ASHRL, O_r, O_l_rp},
   544  	{Vins, O_a0, O_r, O_l_hi, Vgo},
   545  	{V_p0, V_s0},
   546  	{Vins, O_a0, O_r, O_l_hi},
   547  	{Vins, AMOVL, O_l_hi, O_l_lo},
   548  	{V_T1, Vzero, O_l_hi},
   549  	{V_F1, Vins, ASARL, C31, O_l_hi},
   550  	{V_p0, Vend},
   551  };
   552  
   553  /* shift right rp, const < 32 */
   554  static uchar	shrlc0[][VLEN] =
   555  {
   556  	{Vinsr, ASHRL, O_r, O_l_rp},
   557  	{Vins, O_a0, O_r, O_l_hi, Vend},
   558  };
   559  
   560  /* shift right rp, const == 32 */
   561  static uchar	shrlc1[][VLEN] =
   562  {
   563  	{Vins, AMOVL, O_l_hi, O_l_lo},
   564  	{V_T1, Vzero, O_l_hi},
   565  	{V_F1, Vins, ASARL, C31, O_l_hi},
   566  	{Vend},
   567  };
   568  
   569  /* shift right rp, const > 32 */
   570  static uchar	shrlc2[][VLEN] =
   571  {
   572  	{Vins, O_a0, O_r, O_l_hi},
   573  	{Vins, AMOVL, O_l_hi, O_l_lo},
   574  	{V_T1, Vzero, O_l_hi},
   575  	{V_F1, Vins, ASARL, C31, O_l_hi},
   576  	{Vend},
   577  };
   578  
   579  /* shift right addr, const == 32 */
   580  static uchar	shrlac3[][VLEN] =
   581  {
   582  	{Vins, AMOVL, O_l_hi, O_t_lo},
   583  	{V_T1, Vzero, O_t_hi},
   584  	{V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
   585  	{V_F1, Vins, ASARL, C31, O_t_hi},
   586  	{Vend},
   587  };
   588  
   589  /* shift right addr, const > 32 */
   590  static uchar	shrlac4[][VLEN] =
   591  {
   592  	{Vins, AMOVL, O_l_hi, O_t_lo},
   593  	{Vins, O_a0, O_r, O_t_lo},
   594  	{V_T1, Vzero, O_t_hi},
   595  	{V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
   596  	{V_F1, Vins, ASARL, C31, O_t_hi},
   597  	{Vend},
   598  };
   599  
   600  /* shift right of constant */
   601  static uchar	shrl10[][VLEN] =
   602  {
   603  	{Vop, OGE, O_r, C32},
   604  	{V_s0, Vins, AMOVL, O_l_lo, O_t_lo},
   605  	{Vins, AMOVL, O_l_hi, O_t_hi},
   606  	{Vinsr, ASHRL, O_r, O_t_rp},
   607  	{Vins, O_a0, O_r, O_t_hi, Vgo},
   608  	{V_p0, V_s0},
   609  	{Vins, AMOVL, O_l_hi, O_t_lo},
   610  	{V_l_hi_t, Vins, O_a0, O_r, O_t_lo},
   611  	{V_l_hi_u, V_S1},
   612  	{V_T1, Vzero, O_t_hi, V_p0},
   613  	{V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
   614  	{V_F1, Vins, ASARL, C31, O_t_hi},
   615  	{Vend},
   616  };
   617  
   618  static uchar	(*shrltab[])[VLEN] =
   619  {
   620  	shrl00,
   621  	shrlc0,
   622  	shrlc1,
   623  	shrlc2,
   624  	shrlac3,
   625  	shrlac4,
   626  	shrl10,
   627  };
   628  
   629  /* shift asop left general case */
   630  static uchar	asshllgen[][VLEN] =
   631  {
   632  	{V_a0, V_a1},
   633  	{Vop, OGE, O_r, C32},
   634  	{V_s0, Vins, AMOVL, O_l_lo, O_r0},
   635  	{Vins, AMOVL, O_l_hi, O_r1},
   636  	{Vinsla, ASHLL, O_r, O_r0},
   637  	{Vins, ASHLL, O_r, O_r0},
   638  	{Vins, AMOVL, O_r1, O_l_hi},
   639  	{Vins, AMOVL, O_r0, O_l_lo, Vgo},
   640  	{V_p0, V_s0},
   641  	{Vins, AMOVL, O_l_lo, O_r0},
   642  	{Vzero, O_l_lo},
   643  	{Vins, ASHLL, O_r, O_r0},
   644  	{Vins, AMOVL, O_r0, O_l_hi, V_p0},
   645  	{V_f0, V_f1, Vend},
   646  };
   647  
   648  /* shift asop left, const < 32 */
   649  static uchar	asshllclo[][VLEN] =
   650  {
   651  	{V_a0, V_a1},
   652  	{Vins, AMOVL, O_l_lo, O_r0},
   653  	{Vins, AMOVL, O_l_hi, O_r1},
   654  	{Vinsla, ASHLL, O_r, O_r0},
   655  	{Vshll, O_r, O_r0},
   656  	{Vins, AMOVL, O_r1, O_l_hi},
   657  	{Vins, AMOVL, O_r0, O_l_lo},
   658  	{V_f0, V_f1, Vend},
   659  };
   660  
   661  /* shift asop left, const == 32 */
   662  static uchar	asshllc32[][VLEN] =
   663  {
   664  	{V_a0},
   665  	{Vins, AMOVL, O_l_lo, O_r0},
   666  	{Vzero, O_l_lo},
   667  	{Vins, AMOVL, O_r0, O_l_hi},
   668  	{V_f0, Vend},
   669  };
   670  
   671  /* shift asop left, const > 32 */
   672  static uchar	asshllchi[][VLEN] =
   673  {
   674  	{V_a0},
   675  	{Vins, AMOVL, O_l_lo, O_r0},
   676  	{Vzero, O_l_lo},
   677  	{Vshll, O_r, O_r0},
   678  	{Vins, AMOVL, O_r0, O_l_hi},
   679  	{V_f0, Vend},
   680  };
   681  
   682  /* shift asop dest left general case */
   683  static uchar	asdshllgen[][VLEN] =
   684  {
   685  	{Vop, OGE, O_r, C32},
   686  	{V_s0, Vins, AMOVL, O_l_lo, O_t_lo},
   687  	{Vins, AMOVL, O_l_hi, O_t_hi},
   688  	{Vinsl, ASHLL, O_r, O_t_rp},
   689  	{Vins, ASHLL, O_r, O_t_lo},
   690  	{Vins, AMOVL, O_t_hi, O_l_hi},
   691  	{Vins, AMOVL, O_t_lo, O_l_lo, Vgo},
   692  	{V_p0, V_s0},
   693  	{Vins, AMOVL, O_l_lo, O_t_hi},
   694  	{Vzero, O_l_lo},
   695  	{Vins, ASHLL, O_r, O_t_hi},
   696  	{Vzero, O_t_lo},
   697  	{Vins, AMOVL, O_t_hi, O_l_hi, V_p0},
   698  	{Vend},
   699  };
   700  
   701  /* shift asop dest left, const < 32 */
   702  static uchar	asdshllclo[][VLEN] =
   703  {
   704  	{Vins, AMOVL, O_l_lo, O_t_lo},
   705  	{Vins, AMOVL, O_l_hi, O_t_hi},
   706  	{Vinsl, ASHLL, O_r, O_t_rp},
   707  	{Vshll, O_r, O_t_lo},
   708  	{Vins, AMOVL, O_t_hi, O_l_hi},
   709  	{Vins, AMOVL, O_t_lo, O_l_lo},
   710  	{Vend},
   711  };
   712  
   713  /* shift asop dest left, const == 32 */
   714  static uchar	asdshllc32[][VLEN] =
   715  {
   716  	{Vins, AMOVL, O_l_lo, O_t_hi},
   717  	{Vzero, O_t_lo},
   718  	{Vins, AMOVL, O_t_hi, O_l_hi},
   719  	{Vins, AMOVL, O_t_lo, O_l_lo},
   720  	{Vend},
   721  };
   722  
   723  /* shift asop dest, const > 32 */
   724  static uchar	asdshllchi[][VLEN] =
   725  {
   726  	{Vins, AMOVL, O_l_lo, O_t_hi},
   727  	{Vzero, O_t_lo},
   728  	{Vshll, O_r, O_t_hi},
   729  	{Vins, AMOVL, O_t_lo, O_l_lo},
   730  	{Vins, AMOVL, O_t_hi, O_l_hi},
   731  	{Vend},
   732  };
   733  
   734  static uchar	(*asshlltab[])[VLEN] =
   735  {
   736  	asshllgen,
   737  	asshllclo,
   738  	asshllc32,
   739  	asshllchi,
   740  	asdshllgen,
   741  	asdshllclo,
   742  	asdshllc32,
   743  	asdshllchi,
   744  };
   745  
   746  /* shift asop right general case */
   747  static uchar	asshrlgen[][VLEN] =
   748  {
   749  	{V_a0, V_a1},
   750  	{Vop, OGE, O_r, C32},
   751  	{V_s0, Vins, AMOVL, O_l_lo, O_r0},
   752  	{Vins, AMOVL, O_l_hi, O_r1},
   753  	{Vinsra, ASHRL, O_r, O_r0},
   754  	{Vinsx, Bop0, O_r, O_r1},
   755  	{Vins, AMOVL, O_r0, O_l_lo},
   756  	{Vins, AMOVL, O_r1, O_l_hi, Vgo},
   757  	{V_p0, V_s0},
   758  	{Vins, AMOVL, O_l_hi, O_r0},
   759  	{Vinsx, Bop0, O_r, O_r0},
   760  	{V_T1, Vzero, O_l_hi},
   761  	{Vins, AMOVL, O_r0, O_l_lo},
   762  	{V_F1, Vins, ASARL, C31, O_r0},
   763  	{V_F1, Vins, AMOVL, O_r0, O_l_hi},
   764  	{V_p0, V_f0, V_f1, Vend},
   765  };
   766  
   767  /* shift asop right, const < 32 */
   768  static uchar	asshrlclo[][VLEN] =
   769  {
   770  	{V_a0, V_a1},
   771  	{Vins, AMOVL, O_l_lo, O_r0},
   772  	{Vins, AMOVL, O_l_hi, O_r1},
   773  	{Vinsra, ASHRL, O_r, O_r0},
   774  	{Vinsx, Bop0, O_r, O_r1},
   775  	{Vins, AMOVL, O_r0, O_l_lo},
   776  	{Vins, AMOVL, O_r1, O_l_hi},
   777  	{V_f0, V_f1, Vend},
   778  };
   779  
   780  /* shift asop right, const == 32 */
   781  static uchar	asshrlc32[][VLEN] =
   782  {
   783  	{V_a0},
   784  	{Vins, AMOVL, O_l_hi, O_r0},
   785  	{V_T1, Vzero, O_l_hi},
   786  	{Vins, AMOVL, O_r0, O_l_lo},
   787  	{V_F1, Vins, ASARL, C31, O_r0},
   788  	{V_F1, Vins, AMOVL, O_r0, O_l_hi},
   789  	{V_f0, Vend},
   790  };
   791  
   792  /* shift asop right, const > 32 */
   793  static uchar	asshrlchi[][VLEN] =
   794  {
   795  	{V_a0},
   796  	{Vins, AMOVL, O_l_hi, O_r0},
   797  	{V_T1, Vzero, O_l_hi},
   798  	{Vinsx, Bop0, O_r, O_r0},
   799  	{Vins, AMOVL, O_r0, O_l_lo},
   800  	{V_F1, Vins, ASARL, C31, O_r0},
   801  	{V_F1, Vins, AMOVL, O_r0, O_l_hi},
   802  	{V_f0, Vend},
   803  };
   804  
   805  /* shift asop dest right general case */
   806  static uchar	asdshrlgen[][VLEN] =
   807  {
   808  	{Vop, OGE, O_r, C32},
   809  	{V_s0, Vins, AMOVL, O_l_lo, O_t_lo},
   810  	{Vins, AMOVL, O_l_hi, O_t_hi},
   811  	{Vinsr, ASHRL, O_r, O_t_rp},
   812  	{Vinsx, Bop0, O_r, O_t_hi},
   813  	{Vins, AMOVL, O_t_lo, O_l_lo},
   814  	{Vins, AMOVL, O_t_hi, O_l_hi, Vgo},
   815  	{V_p0, V_s0},
   816  	{Vins, AMOVL, O_l_hi, O_t_lo},
   817  	{V_T1, Vzero, O_t_hi},
   818  	{Vinsx, Bop0, O_r, O_t_lo},
   819  	{V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
   820  	{V_F1, Vins, ASARL, C31, O_t_hi},
   821  	{Vins, AMOVL, O_t_hi, O_l_hi, V_p0},
   822  	{Vend},
   823  };
   824  
   825  /* shift asop dest right, const < 32 */
   826  static uchar	asdshrlclo[][VLEN] =
   827  {
   828  	{Vins, AMOVL, O_l_lo, O_t_lo},
   829  	{Vins, AMOVL, O_l_hi, O_t_hi},
   830  	{Vinsr, ASHRL, O_r, O_t_rp},
   831  	{Vinsx, Bop0, O_r, O_t_hi},
   832  	{Vins, AMOVL, O_t_lo, O_l_lo},
   833  	{Vins, AMOVL, O_t_hi, O_l_hi},
   834  	{Vend},
   835  };
   836  
   837  /* shift asop dest right, const == 32 */
   838  static uchar	asdshrlc32[][VLEN] =
   839  {
   840  	{Vins, AMOVL, O_l_hi, O_t_lo},
   841  	{V_T1, Vzero, O_t_hi},
   842  	{V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
   843  	{V_F1, Vins, ASARL, C31, O_t_hi},
   844  	{Vins, AMOVL, O_t_lo, O_l_lo},
   845  	{Vins, AMOVL, O_t_hi, O_l_hi},
   846  	{Vend},
   847  };
   848  
   849  /* shift asop dest, const > 32 */
   850  static uchar	asdshrlchi[][VLEN] =
   851  {
   852  	{Vins, AMOVL, O_l_hi, O_t_lo},
   853  	{V_T1, Vzero, O_t_hi},
   854  	{Vinsx, Bop0, O_r, O_t_lo},
   855  	{V_T1, Vins, AMOVL, O_t_hi, O_l_hi},
   856  	{V_T1, Vins, AMOVL, O_t_lo, O_l_lo},
   857  	{V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
   858  	{V_F1, Vins, ASARL, C31, O_t_hi},
   859  	{V_F1, Vins, AMOVL, O_t_lo, O_l_lo},
   860  	{V_F1, Vins, AMOVL, O_t_hi, O_l_hi},
   861  	{Vend},
   862  };
   863  
   864  static uchar	(*asshrltab[])[VLEN] =
   865  {
   866  	asshrlgen,
   867  	asshrlclo,
   868  	asshrlc32,
   869  	asshrlchi,
   870  	asdshrlgen,
   871  	asdshrlclo,
   872  	asdshrlc32,
   873  	asdshrlchi,
   874  };
   875  
   876  static uchar	shrlargs[]	= { ASHRL, 1 };
   877  static uchar	sarlargs[]	= { ASARL, 0 };
   878  
   879  /* ++ -- */
   880  static uchar	incdec[][VLEN] =
   881  {
   882  	{Vinsx, Bop0, C01, O_l_lo},
   883  	{Vinsx, Bop1, C00, O_l_hi, Vend},
   884  };
   885  
   886  /* ++ -- *p */
   887  static uchar	incdecpre[][VLEN] =
   888  {
   889  	{Vins, AMOVL, O_l_lo, O_t_lo},
   890  	{Vins, AMOVL, O_l_hi, O_t_hi},
   891  	{Vinsx, Bop0, C01, O_t_lo},
   892  	{Vinsx, Bop1, C00, O_t_hi},
   893  	{Vins, AMOVL, O_t_lo, O_l_lo},
   894  	{Vins, AMOVL, O_t_hi, O_l_hi, Vend},
   895  };
   896  
   897  /* *p ++ -- */
   898  static uchar	incdecpost[][VLEN] =
   899  {
   900  	{Vins, AMOVL, O_l_lo, O_t_lo},
   901  	{Vins, AMOVL, O_l_hi, O_t_hi},
   902  	{Vinsx, Bop0, C01, O_l_lo},
   903  	{Vinsx, Bop1, C00, O_l_hi, Vend},
   904  };
   905  
   906  /* binop rp, rp */
   907  static uchar	binop00[][VLEN] =
   908  {
   909  	{Vinsx, Bop0, O_r_lo, O_l_lo},
   910  	{Vinsx, Bop1, O_r_hi, O_l_hi, Vend},
   911  	{Vend},
   912  };
   913  
   914  /* binop rp, addr */
   915  static uchar	binoptmp[][VLEN] =
   916  {
   917  	{V_a0, Vins, AMOVL, O_r_lo, O_r0},
   918  	{Vinsx, Bop0, O_r0, O_l_lo},
   919  	{Vins, AMOVL, O_r_hi, O_r0},
   920  	{Vinsx, Bop1, O_r0, O_l_hi},
   921  	{V_f0, Vend},
   922  };
   923  
   924  /* binop t = *a op *b */
   925  static uchar	binop11[][VLEN] =
   926  {
   927  	{Vins, AMOVL, O_l_lo, O_t_lo},
   928  	{Vinsx, Bop0, O_r_lo, O_t_lo},
   929  	{Vins, AMOVL, O_l_hi, O_t_hi},
   930  	{Vinsx, Bop1, O_r_hi, O_t_hi, Vend},
   931  };
   932  
   933  /* binop t = rp +- c */
   934  static uchar	add0c[][VLEN] =
   935  {
   936  	{V_r_lo_t, Vinsx, Bop0, O_r_lo, O_l_lo},
   937  	{V_r_lo_f, Vamv, Bop0, Bop1},
   938  	{Vinsx, Bop1, O_r_hi, O_l_hi},
   939  	{Vend},
   940  };
   941  
   942  /* binop t = rp & c */
   943  static uchar	and0c[][VLEN] =
   944  {
   945  	{V_r_lo_t, Vinsx, Bop0, O_r_lo, O_l_lo},
   946  	{V_r_lo_f, Vins, AMOVL, C00, O_l_lo},
   947  	{V_r_hi_t, Vinsx, Bop1, O_r_hi, O_l_hi},
   948  	{V_r_hi_f, Vins, AMOVL, C00, O_l_hi},
   949  	{Vend},
   950  };
   951  
   952  /* binop t = rp | c */
   953  static uchar	or0c[][VLEN] =
   954  {
   955  	{V_r_lo_t, Vinsx, Bop0, O_r_lo, O_l_lo},
   956  	{V_r_hi_t, Vinsx, Bop1, O_r_hi, O_l_hi},
   957  	{Vend},
   958  };
   959  
   960  /* binop t = c - rp */
   961  static uchar	sub10[][VLEN] =
   962  {
   963  	{V_a0, Vins, AMOVL, O_l_lo, O_r0},
   964  	{Vinsx, Bop0, O_r_lo, O_r0},
   965  	{Vins, AMOVL, O_l_hi, O_r_lo},
   966  	{Vinsx, Bop1, O_r_hi, O_r_lo},
   967  	{Vspazz, V_f0, Vend},
   968  };
   969  
   970  /* binop t = c + *b */
   971  static uchar	addca[][VLEN] =
   972  {
   973  	{Vins, AMOVL, O_r_lo, O_t_lo},
   974  	{V_l_lo_t, Vinsx, Bop0, O_l_lo, O_t_lo},
   975  	{V_l_lo_f, Vamv, Bop0, Bop1},
   976  	{Vins, AMOVL, O_r_hi, O_t_hi},
   977  	{Vinsx, Bop1, O_l_hi, O_t_hi},
   978  	{Vend},
   979  };
   980  
   981  /* binop t = c & *b */
   982  static uchar	andca[][VLEN] =
   983  {
   984  	{V_l_lo_t, Vins, AMOVL, O_r_lo, O_t_lo},
   985  	{V_l_lo_t, Vinsx, Bop0, O_l_lo, O_t_lo},
   986  	{V_l_lo_f, Vzero, O_t_lo},
   987  	{V_l_hi_t, Vins, AMOVL, O_r_hi, O_t_hi},
   988  	{V_l_hi_t, Vinsx, Bop1, O_l_hi, O_t_hi},
   989  	{V_l_hi_f, Vzero, O_t_hi},
   990  	{Vend},
   991  };
   992  
   993  /* binop t = c | *b */
   994  static uchar	orca[][VLEN] =
   995  {
   996  	{Vins, AMOVL, O_r_lo, O_t_lo},
   997  	{V_l_lo_t, Vinsx, Bop0, O_l_lo, O_t_lo},
   998  	{Vins, AMOVL, O_r_hi, O_t_hi},
   999  	{V_l_hi_t, Vinsx, Bop1, O_l_hi, O_t_hi},
  1000  	{Vend},
  1001  };
  1002  
  1003  /* binop t = c - *b */
  1004  static uchar	subca[][VLEN] =
  1005  {
  1006  	{Vins, AMOVL, O_l_lo, O_t_lo},
  1007  	{Vins, AMOVL, O_l_hi, O_t_hi},
  1008  	{Vinsx, Bop0, O_r_lo, O_t_lo},
  1009  	{Vinsx, Bop1, O_r_hi, O_t_hi},
  1010  	{Vend},
  1011  };
  1012  
  1013  /* binop t = *a +- c */
  1014  static uchar	addac[][VLEN] =
  1015  {
  1016  	{Vins, AMOVL, O_l_lo, O_t_lo},
  1017  	{V_r_lo_t, Vinsx, Bop0, O_r_lo, O_t_lo},
  1018  	{V_r_lo_f, Vamv, Bop0, Bop1},
  1019  	{Vins, AMOVL, O_l_hi, O_t_hi},
  1020  	{Vinsx, Bop1, O_r_hi, O_t_hi},
  1021  	{Vend},
  1022  };
  1023  
  1024  /* binop t = *a | c */
  1025  static uchar	orac[][VLEN] =
  1026  {
  1027  	{Vins, AMOVL, O_l_lo, O_t_lo},
  1028  	{V_r_lo_t, Vinsx, Bop0, O_r_lo, O_t_lo},
  1029  	{Vins, AMOVL, O_l_hi, O_t_hi},
  1030  	{V_r_hi_t, Vinsx, Bop1, O_r_hi, O_t_hi},
  1031  	{Vend},
  1032  };
  1033  
  1034  /* binop t = *a & c */
  1035  static uchar	andac[][VLEN] =
  1036  {
  1037  	{V_r_lo_t, Vins, AMOVL, O_l_lo, O_t_lo},
  1038  	{V_r_lo_t, Vinsx, Bop0, O_r_lo, O_t_lo},
  1039  	{V_r_lo_f, Vzero, O_t_lo},
  1040  	{V_r_hi_t, Vins, AMOVL, O_l_hi, O_t_hi},
  1041  	{V_r_hi_t, Vinsx, Bop0, O_r_hi, O_t_hi},
  1042  	{V_r_hi_f, Vzero, O_t_hi},
  1043  	{Vend},
  1044  };
  1045  
  1046  static uchar	ADDargs[]	= { AADDL, AADCL };
  1047  static uchar	ANDargs[]	= { AANDL, AANDL };
  1048  static uchar	ORargs[]	= { AORL, AORL };
  1049  static uchar	SUBargs[]	= { ASUBL, ASBBL };
  1050  static uchar	XORargs[]	= { AXORL, AXORL };
  1051  
  1052  static uchar	(*ADDtab[])[VLEN] =
  1053  {
  1054  	add0c, addca, addac,
  1055  };
  1056  
  1057  static uchar	(*ANDtab[])[VLEN] =
  1058  {
  1059  	and0c, andca, andac,
  1060  };
  1061  
  1062  static uchar	(*ORtab[])[VLEN] =
  1063  {
  1064  	or0c, orca, orac,
  1065  };
  1066  
  1067  static uchar	(*SUBtab[])[VLEN] =
  1068  {
  1069  	add0c, subca, addac,
  1070  };
  1071  
  1072  /* mul of const32 */
  1073  static uchar	mulc32[][VLEN] =
  1074  {
  1075  	{V_a0, Vop, ONE, O_l_hi, C00},
  1076  	{V_s0, Vins, AMOVL, O_r_lo, O_r0},
  1077  	{Vins, AMULL, O_r0, O_Zop},
  1078  	{Vgo, V_p0, V_s0},
  1079  	{Vins, AMOVL, O_l_hi, O_r0},
  1080  	{Vmul, O_r_lo, O_r0},
  1081  	{Vins, AMOVL, O_r_lo, O_l_hi},
  1082  	{Vins, AMULL, O_l_hi, O_Zop},
  1083  	{Vins, AADDL, O_r0, O_l_hi},
  1084  	{V_f0, V_p0, Vend},
  1085  };
  1086  
  1087  /* mul of const64 */
  1088  static uchar	mulc64[][VLEN] =
  1089  {
  1090  	{V_a0, Vins, AMOVL, O_r_hi, O_r0},
  1091  	{Vop, OOR, O_l_hi, O_r0},
  1092  	{Vop, ONE, O_r0, C00},
  1093  	{V_s0, Vins, AMOVL, O_r_lo, O_r0},
  1094  	{Vins, AMULL, O_r0, O_Zop},
  1095  	{Vgo, V_p0, V_s0},
  1096  	{Vmul, O_r_lo, O_l_hi},
  1097  	{Vins, AMOVL, O_l_lo, O_r0},
  1098  	{Vmul, O_r_hi, O_r0},
  1099  	{Vins, AADDL, O_l_hi, O_r0},
  1100  	{Vins, AMOVL, O_r_lo, O_l_hi},
  1101  	{Vins, AMULL, O_l_hi, O_Zop},
  1102  	{Vins, AADDL, O_r0, O_l_hi},
  1103  	{V_f0, V_p0, Vend},
  1104  };
  1105  
  1106  /* mul general */
  1107  static uchar	mull[][VLEN] =
  1108  {
  1109  	{V_a0, Vins, AMOVL, O_r_hi, O_r0},
  1110  	{Vop, OOR, O_l_hi, O_r0},
  1111  	{Vop, ONE, O_r0, C00},
  1112  	{V_s0, Vins, AMOVL, O_r_lo, O_r0},
  1113  	{Vins, AMULL, O_r0, O_Zop},
  1114  	{Vgo, V_p0, V_s0},
  1115  	{Vins, AIMULL, O_r_lo, O_l_hi},
  1116  	{Vins, AMOVL, O_l_lo, O_r0},
  1117  	{Vins, AIMULL, O_r_hi, O_r0},
  1118  	{Vins, AADDL, O_l_hi, O_r0},
  1119  	{Vins, AMOVL, O_r_lo, O_l_hi},
  1120  	{Vins, AMULL, O_l_hi, O_Zop},
  1121  	{Vins, AADDL, O_r0, O_l_hi},
  1122  	{V_f0, V_p0, Vend},
  1123  };
  1124  
  1125  /* cast rp l to rp t */
  1126  static uchar	castrp[][VLEN] =
  1127  {
  1128  	{Vmv, O_l, O_t_lo},
  1129  	{VT, Vins, AMOVL, O_t_lo, O_t_hi},
  1130  	{VT, Vins, ASARL, C31, O_t_hi},
  1131  	{VF, Vzero, O_t_hi},
  1132  	{Vend},
  1133  };
  1134  
  1135  /* cast rp l to addr t */
  1136  static uchar	castrpa[][VLEN] =
  1137  {
  1138  	{VT, V_a0, Vmv, O_l, O_r0},
  1139  	{VT, Vins, AMOVL, O_r0, O_t_lo},
  1140  	{VT, Vins, ASARL, C31, O_r0},
  1141  	{VT, Vins, AMOVL, O_r0, O_t_hi},
  1142  	{VT, V_f0},
  1143  	{VF, Vmv, O_l, O_t_lo},
  1144  	{VF, Vzero, O_t_hi},
  1145  	{Vend},
  1146  };
  1147  
  1148  static uchar	netab0i[][VLEN] =
  1149  {
  1150  	{Vop, ONE, O_l_lo, O_r_lo},
  1151  	{V_s0, Vop, ONE, O_l_hi, O_r_hi},
  1152  	{V_s1, Vgo, V_s2, Vgo, V_s3},
  1153  	{VF, V_p0, V_p1, VT, V_p2},
  1154  	{Vgo, V_p3},
  1155  	{VT, V_p0, V_p1, VF, V_p2},
  1156  	{Vend},
  1157  };
  1158  
  1159  static uchar	netabii[][VLEN] =
  1160  {
  1161  	{V_a0, Vins, AMOVL, O_l_lo, O_r0},
  1162  	{Vop, ONE, O_r0, O_r_lo},
  1163  	{V_s0, Vins, AMOVL, O_l_hi, O_r0},
  1164  	{Vop, ONE, O_r0, O_r_hi},
  1165  	{V_s1, Vgo, V_s2, Vgo, V_s3},
  1166  	{VF, V_p0, V_p1, VT, V_p2},
  1167  	{Vgo, V_p3},
  1168  	{VT, V_p0, V_p1, VF, V_p2},
  1169  	{V_f0, Vend},
  1170  };
  1171  
  1172  static uchar	cmptab0i[][VLEN] =
  1173  {
  1174  	{Vopx, Bop0, O_l_hi, O_r_hi},
  1175  	{V_s0, Vins0, AJNE},
  1176  	{V_s1, Vopx, Bop1, O_l_lo, O_r_lo},
  1177  	{V_s2, Vgo, V_s3, Vgo, V_s4},
  1178  	{VT, V_p1, V_p3},
  1179  	{VF, V_p0, V_p2},
  1180  	{Vgo, V_p4},
  1181  	{VT, V_p0, V_p2},
  1182  	{VF, V_p1, V_p3},
  1183  	{Vend},
  1184  };
  1185  
  1186  static uchar	cmptabii[][VLEN] =
  1187  {
  1188  	{V_a0, Vins, AMOVL, O_l_hi, O_r0},
  1189  	{Vopx, Bop0, O_r0, O_r_hi},
  1190  	{V_s0, Vins0, AJNE},
  1191  	{V_s1, Vins, AMOVL, O_l_lo, O_r0},
  1192  	{Vopx, Bop1, O_r0, O_r_lo},
  1193  	{V_s2, Vgo, V_s3, Vgo, V_s4},
  1194  	{VT, V_p1, V_p3},
  1195  	{VF, V_p0, V_p2},
  1196  	{Vgo, V_p4},
  1197  	{VT, V_p0, V_p2},
  1198  	{VF, V_p1, V_p3},
  1199  	{V_f0, Vend},
  1200  };
  1201  
  1202  static uchar	(*NEtab[])[VLEN] =
  1203  {
  1204  	netab0i, netabii,
  1205  };
  1206  
  1207  static uchar	(*cmptab[])[VLEN] =
  1208  {
  1209  	cmptab0i, cmptabii,
  1210  };
  1211  
  1212  static uchar	GEargs[]	= { OGT, OHS };
  1213  static uchar	GTargs[]	= { OGT, OHI };
  1214  static uchar	HIargs[]	= { OHI, OHI };
  1215  static uchar	HSargs[]	= { OHI, OHS };
  1216  
  1217  /* Big Generator */
  1218  static void
  1219  biggen(Node *l, Node *r, Node *t, int true, uchar code[][VLEN], uchar *a)
  1220  {
  1221  	int i, j, g, oc, op, lo, ro, to, xo, *xp;
  1222  	Type *lt;
  1223  	Prog *pr[VOPS];
  1224  	Node *ot, *tl, *tr, tmps[2];
  1225  	uchar *c, (*cp)[VLEN], args[VARGS];
  1226  
  1227  	if(a != nil)
  1228  		memmove(args, a, VARGS);
  1229  //print("biggen %d %d %d\n", args[0], args[1], args[2]);
  1230  //if(l) prtree(l, "l");
  1231  //if(r) prtree(r, "r");
  1232  //if(t) prtree(t, "t");
  1233  	lo = ro = to = 0;
  1234  	cp = code;
  1235  
  1236  	for (;;) {
  1237  		c = *cp++;
  1238  		g = 1;
  1239  		i = 0;
  1240  //print("code %d %d %d %d %d\n", c[0], c[1], c[2], c[3], c[4]);
  1241  		for(;;) {
  1242  			switch(op = c[i]) {
  1243  			case Vgo:
  1244  				if(g)
  1245  					gbranch(OGOTO);
  1246  				i++;
  1247  				break;
  1248  
  1249  			case Vamv:
  1250  				i += 3;
  1251  				if(i > VLEN) {
  1252  					diag(l, "bad Vop");
  1253  					return;
  1254  				}
  1255  				if(g)
  1256  					args[c[i - 1]] = args[c[i - 2]];
  1257  				break;
  1258  
  1259  			case Vzero:
  1260  				i += 2;
  1261  				if(i > VLEN) {
  1262  					diag(l, "bad Vop");
  1263  					return;
  1264  				}
  1265  				j = i - 1;
  1266  				goto op;
  1267  
  1268  			case Vspazz:	// nasty hack to save a reg in SUB
  1269  //print("spazz\n");
  1270  				if(g) {
  1271  //print("hi %R lo %R t %R\n", r->right->reg, r->left->reg, tmps[0].reg);
  1272  					ot = r->right;
  1273  					r->right = r->left;
  1274  					tl = new(0, Z, Z);
  1275  					*tl = tmps[0];
  1276  					r->left = tl;
  1277  					tmps[0] = *ot;
  1278  //print("hi %R lo %R t %R\n", r->right->reg, r->left->reg, tmps[0].reg);
  1279  				}
  1280  				i++;
  1281  				break;
  1282  
  1283  			case Vmv:
  1284  			case Vmul:
  1285  			case Vshll:
  1286  				i += 3;
  1287  				if(i > VLEN) {
  1288  					diag(l, "bad Vop");
  1289  					return;
  1290  				}
  1291  				j = i - 2;
  1292  				goto op;
  1293  
  1294  			case Vins0:
  1295  				i += 2;
  1296  				if(i > VLEN) {
  1297  					diag(l, "bad Vop");
  1298  					return;
  1299  				}
  1300  				gins(c[i - 1], Z, Z);
  1301  				break;
  1302  
  1303  			case Vop:
  1304  			case Vopx:
  1305  			case Vins:
  1306  			case Vinsl:
  1307  			case Vinsr:
  1308  			case Vinsla:
  1309  			case Vinsra:
  1310  			case Vinsx:
  1311  				i += 4;
  1312  				if(i > VLEN) {
  1313  					diag(l, "bad Vop");
  1314  					return;
  1315  				}
  1316  				j = i - 2;
  1317  				goto op;
  1318  
  1319  			op:
  1320  				if(!g)
  1321  					break;
  1322  				tl = Z;
  1323  				tr = Z;
  1324  				for(; j < i; j++) {
  1325  					switch(c[j]) {
  1326  					case C00:
  1327  						ot = nodconst(0);
  1328  						break;
  1329  					case C01:
  1330  						ot = nodconst(1);
  1331  						break;
  1332  					case C31:
  1333  						ot = nodconst(31);
  1334  						break;
  1335  					case C32:
  1336  						ot = nodconst(32);
  1337  						break;
  1338  
  1339  					case O_l:
  1340  					case O_l_lo:
  1341  						ot = l; xp = &lo; xo = 0;
  1342  						goto op0;
  1343  					case O_l_hi:
  1344  						ot = l; xp = &lo; xo = SZ_LONG;
  1345  						goto op0;
  1346  					case O_r:
  1347  					case O_r_lo:
  1348  						ot = r; xp = &ro; xo = 0;
  1349  						goto op0;
  1350  					case O_r_hi:
  1351  						ot = r; xp = &ro; xo = SZ_LONG;
  1352  						goto op0;
  1353  					case O_t_lo:
  1354  						ot = t; xp = &to; xo = 0;
  1355  						goto op0;
  1356  					case O_t_hi:
  1357  						ot = t; xp = &to; xo = SZ_LONG;
  1358  						goto op0;
  1359  					case O_l_rp:
  1360  						ot = l;
  1361  						break;
  1362  					case O_r_rp:
  1363  						ot = r;
  1364  						break;
  1365  					case O_t_rp:
  1366  						ot = t;
  1367  						break;
  1368  					case O_r0:
  1369  					case O_r1:
  1370  						ot = &tmps[c[j] - O_r0];
  1371  						break;
  1372  					case O_Zop:
  1373  						ot = Z;
  1374  						break;
  1375  
  1376  					op0:
  1377  						switch(ot->op) {
  1378  						case OCONST:
  1379  							if(xo)
  1380  								ot = hi64(ot);
  1381  							else
  1382  								ot = lo64(ot);
  1383  							break;
  1384  						case OREGPAIR:
  1385  							if(xo)
  1386  								ot = ot->right;
  1387  							else
  1388  								ot = ot->left;
  1389  							break;
  1390  						case OREGISTER:
  1391  							break;
  1392  						default:
  1393  							if(xo != *xp) {
  1394  								ot->xoffset += xo - *xp;
  1395  								*xp = xo;
  1396  							}
  1397  						}
  1398  						break;
  1399  					
  1400  					default:
  1401  						diag(l, "bad V_lop");
  1402  						return;
  1403  					}
  1404  					if(tl == nil)
  1405  						tl = ot;
  1406  					else
  1407  						tr = ot;
  1408  				}
  1409  				if(op == Vzero) {
  1410  					zeroregm(tl);
  1411  					break;
  1412  				}
  1413  				oc = c[i - 3];
  1414  				if(op == Vinsx || op == Vopx) {
  1415  //print("%d -> %d\n", oc, args[oc]);
  1416  					oc = args[oc];
  1417  				}
  1418  				else {
  1419  					switch(oc) {
  1420  					case O_a0:
  1421  					case O_a1:
  1422  						oc = args[oc - O_a0];
  1423  						break;
  1424  					}
  1425  				}
  1426  				switch(op) {
  1427  				case Vmul:
  1428  					mulgen(tr->type, tl, tr);
  1429  					break;
  1430  				case Vmv:
  1431  					gmove(tl, tr);
  1432  					break;
  1433  				case Vshll:
  1434  					shiftit(tr->type, tl, tr);
  1435  					break;
  1436  				case Vop:
  1437  				case Vopx:
  1438  					gopcode(oc, types[TULONG], tl, tr);
  1439  					break;
  1440  				case Vins:
  1441  				case Vinsx:
  1442  					gins(oc, tl, tr);
  1443  					break;
  1444  				case Vinsl:
  1445  					gins(oc, tl, tr->right);
  1446  					p->from.index = tr->left->reg;
  1447  					break;
  1448  				case Vinsr:
  1449  					gins(oc, tl, tr->left);
  1450  					p->from.index = tr->right->reg;
  1451  					break;
  1452  				case Vinsla:
  1453  					gins(oc, tl, tr + 1);
  1454  					p->from.index = tr->reg;
  1455  					break;
  1456  				case Vinsra:
  1457  					gins(oc, tl, tr);
  1458  					p->from.index = (tr + 1)->reg;
  1459  					break;
  1460  				}
  1461  				break;
  1462  
  1463  			case VT:
  1464  				g = true;
  1465  				i++;
  1466  				break;
  1467  			case VF:
  1468  				g = !true;
  1469  				i++;
  1470  				break;
  1471  
  1472  			case V_T0: case V_T1:
  1473  				g = args[op - V_T0];
  1474  				i++;
  1475  				break;
  1476  
  1477  			case V_F0: case V_F1:
  1478  				g = !args[op - V_F0];
  1479  				i++;
  1480  				break;
  1481  
  1482  			case V_C0: case V_C1:
  1483  				if(g)
  1484  					args[op - V_C0] = 0;
  1485  				i++;
  1486  				break;
  1487  
  1488  			case V_S0: case V_S1:
  1489  				if(g)
  1490  					args[op - V_S0] = 1;
  1491  				i++;
  1492  				break;
  1493  
  1494  			case V_l_lo_f:
  1495  				g = lo64v(l) == 0;
  1496  				i++;
  1497  				break;
  1498  			case V_l_hi_f:
  1499  				g = hi64v(l) == 0;
  1500  				i++;
  1501  				break;
  1502  			case V_l_lo_t:
  1503  				g = lo64v(l) != 0;
  1504  				i++;
  1505  				break;
  1506  			case V_l_hi_t:
  1507  				g = hi64v(l) != 0;
  1508  				i++;
  1509  				break;
  1510  			case V_l_lo_u:
  1511  				g = lo64v(l) >= 0;
  1512  				i++;
  1513  				break;
  1514  			case V_l_hi_u:
  1515  				g = hi64v(l) >= 0;
  1516  				i++;
  1517  				break;
  1518  			case V_r_lo_f:
  1519  				g = lo64v(r) == 0;
  1520  				i++;
  1521  				break;
  1522  			case V_r_hi_f:
  1523  				g = hi64v(r) == 0;
  1524  				i++;
  1525  				break;
  1526  			case V_r_lo_t:
  1527  				g = lo64v(r) != 0;
  1528  				i++;
  1529  				break;
  1530  			case V_r_hi_t:
  1531  				g = hi64v(r) != 0;
  1532  				i++;
  1533  				break;
  1534  			case V_r_lo_u:
  1535  				g = lo64v(r) >= 0;
  1536  				i++;
  1537  				break;
  1538  			case V_r_hi_u:
  1539  				g = hi64v(r) >= 0;
  1540  				i++;
  1541  				break;
  1542  
  1543  			case Vend:
  1544  				goto out;
  1545  
  1546  			case V_a0: case V_a1:
  1547  				if(g) {
  1548  					lt = l->type;
  1549  					l->type = types[TULONG];
  1550  					regalloc(&tmps[op - V_a0], l, Z);
  1551  					l->type = lt;
  1552  				}
  1553  				i++;
  1554  				break;
  1555  
  1556  			case V_f0: case V_f1:
  1557  				if(g)
  1558  					regfree(&tmps[op - V_f0]);
  1559  				i++;
  1560  				break;
  1561  
  1562  			case V_p0: case V_p1: case V_p2: case V_p3: case V_p4:
  1563  				if(g)
  1564  					patch(pr[op - V_p0], pc);
  1565  				i++;
  1566  				break;
  1567  
  1568  			case V_s0: case V_s1: case V_s2: case V_s3: case V_s4:
  1569  				if(g)
  1570  					pr[op - V_s0] = p;
  1571  				i++;
  1572  				break;
  1573  
  1574  			default:
  1575  				diag(l, "bad biggen: %d", op);
  1576  				return;
  1577  			}
  1578  			if(i == VLEN || c[i] == 0)
  1579  				break;
  1580  		}
  1581  	}
  1582  out:
  1583  	if(lo)
  1584  		l->xoffset -= lo;
  1585  	if(ro)
  1586  		r->xoffset -= ro;
  1587  	if(to)
  1588  		t->xoffset -= to;
  1589  }
  1590  
  1591  int
  1592  cgen64(Node *n, Node *nn)
  1593  {
  1594  	Type *dt;
  1595  	uchar *args, (*cp)[VLEN], (**optab)[VLEN];
  1596  	int li, ri, lri, dr, si, m, op, sh, cmp, true;
  1597  	Node *c, *d, *l, *r, *t, *s, nod1, nod2, nod3, nod4, nod5;
  1598  
  1599  	if(debug['g']) {
  1600  		prtree(nn, "cgen64 lhs");
  1601  		prtree(n, "cgen64");
  1602  		print("AX = %d\n", reg[D_AX]);
  1603  	}
  1604  	cmp = 0;
  1605  	sh = 0;
  1606  
  1607  	switch(n->op) {
  1608  	case ONEG:
  1609  		d = regpair(nn, n);
  1610  		sugen(n->left, d, 8);
  1611  		gins(ANOTL, Z, d->right);
  1612  		gins(ANEGL, Z, d->left);
  1613  		gins(ASBBL, nodconst(-1), d->right);
  1614  		break;
  1615  
  1616  	case OCOM:
  1617  		if(!vaddr(n->left, 0) || !vaddr(nn, 0))
  1618  			d = regpair(nn, n);
  1619  		else
  1620  			return 0;
  1621  		sugen(n->left, d, 8);
  1622  		gins(ANOTL, Z, d->left);
  1623  		gins(ANOTL, Z, d->right);
  1624  		break;
  1625  
  1626  	case OADD:
  1627  		optab = ADDtab;
  1628  		args = ADDargs;
  1629  		goto twoop;
  1630  	case OAND:
  1631  		optab = ANDtab;
  1632  		args = ANDargs;
  1633  		goto twoop;
  1634  	case OOR:
  1635  		optab = ORtab;
  1636  		args = ORargs;
  1637  		goto twoop;
  1638  	case OSUB:
  1639  		optab = SUBtab;
  1640  		args = SUBargs;
  1641  		goto twoop;
  1642  	case OXOR:
  1643  		optab = ORtab;
  1644  		args = XORargs;
  1645  		goto twoop;
  1646  	case OASHL:
  1647  		sh = 1;
  1648  		args = nil;
  1649  		optab = shlltab;
  1650  		goto twoop;
  1651  	case OLSHR:
  1652  		sh = 1;
  1653  		args = shrlargs;
  1654  		optab = shrltab;
  1655  		goto twoop;
  1656  	case OASHR:
  1657  		sh = 1;
  1658  		args = sarlargs;
  1659  		optab = shrltab;
  1660  		goto twoop;
  1661  	case OEQ:
  1662  		cmp = 1;
  1663  		args = nil;
  1664  		optab = nil;
  1665  		goto twoop;
  1666  	case ONE:
  1667  		cmp = 1;
  1668  		args = nil;
  1669  		optab = nil;
  1670  		goto twoop;
  1671  	case OLE:
  1672  		cmp = 1;
  1673  		args = nil;
  1674  		optab = nil;
  1675  		goto twoop;
  1676  	case OLT:
  1677  		cmp = 1;
  1678  		args = nil;
  1679  		optab = nil;
  1680  		goto twoop;
  1681  	case OGE:
  1682  		cmp = 1;
  1683  		args = nil;
  1684  		optab = nil;
  1685  		goto twoop;
  1686  	case OGT:
  1687  		cmp = 1;
  1688  		args = nil;
  1689  		optab = nil;
  1690  		goto twoop;
  1691  	case OHI:
  1692  		cmp = 1;
  1693  		args = nil;
  1694  		optab = nil;
  1695  		goto twoop;
  1696  	case OHS:
  1697  		cmp = 1;
  1698  		args = nil;
  1699  		optab = nil;
  1700  		goto twoop;
  1701  	case OLO:
  1702  		cmp = 1;
  1703  		args = nil;
  1704  		optab = nil;
  1705  		goto twoop;
  1706  	case OLS:
  1707  		cmp = 1;
  1708  		args = nil;
  1709  		optab = nil;
  1710  		goto twoop;
  1711  
  1712  twoop:
  1713  		dr = nn != Z && nn->op == OREGPAIR;
  1714  		l = vfunc(n->left, nn);
  1715  		if(sh)
  1716  			r = n->right;
  1717  		else
  1718  			r = vfunc(n->right, nn);
  1719  
  1720  		li = l->op == ONAME || l->op == OINDREG || l->op == OCONST;
  1721  		ri = r->op == ONAME || r->op == OINDREG || r->op == OCONST;
  1722  
  1723  #define	IMM(l, r)	((l) | ((r) << 1))
  1724  
  1725  		lri = IMM(li, ri);
  1726  
  1727  		/* find out what is so easy about some operands */
  1728  		if(li)
  1729  			li = whatof(l, sh | cmp);
  1730  		if(ri)
  1731  			ri = whatof(r, cmp);
  1732  
  1733  		if(sh)
  1734  			goto shift;
  1735  
  1736  		if(cmp)
  1737  			goto cmp;
  1738  
  1739  		/* evaluate hard subexps, stealing nn if possible. */
  1740  		switch(lri) {
  1741  		case IMM(0, 0):
  1742  		bin00:
  1743  			if(l->complex > r->complex) {
  1744  				if(dr)
  1745  					t = nn;
  1746  				else
  1747  					t = regpair(Z, n);
  1748  				sugen(l, t, 8);
  1749  				l = t;
  1750  				t = regpair(Z, n);
  1751  				sugen(r, t, 8);
  1752  				r = t;
  1753  			}
  1754  			else {
  1755  				t = regpair(Z, n);
  1756  				sugen(r, t, 8);
  1757  				r = t;
  1758  				if(dr)
  1759  					t = nn;
  1760  				else
  1761  					t = regpair(Z, n);
  1762  				sugen(l, t, 8);
  1763  				l = t;
  1764  			}
  1765  			break;
  1766  		case IMM(0, 1):
  1767  			if(dr)
  1768  				t = nn;
  1769  			else
  1770  				t = regpair(Z, n);
  1771  			sugen(l, t, 8);
  1772  			l = t;
  1773  			break;
  1774  		case IMM(1, 0):
  1775  			if(n->op == OSUB && l->op == OCONST && hi64v(l) == 0) {
  1776  				lri = IMM(0, 0);
  1777  				goto bin00;
  1778  			}
  1779  			if(dr)
  1780  				t = nn;
  1781  			else
  1782  				t = regpair(Z, n);
  1783  			sugen(r, t, 8);
  1784  			r = t;
  1785  			break;
  1786  		case IMM(1, 1):
  1787  			break;
  1788  		}
  1789  
  1790  #define	WW(l, r)	((l) | ((r) << 2))
  1791  		d = Z;
  1792  		dt = nn->type;
  1793  		nn->type = types[TLONG];
  1794  
  1795  		switch(lri) {
  1796  		case IMM(0, 0):
  1797  			biggen(l, r, Z, 0, binop00, args);
  1798  			break;
  1799  		case IMM(0, 1):
  1800  			switch(ri) {
  1801  			case WNONE:
  1802  				diag(r, "bad whatof\n");
  1803  				break;
  1804  			case WCONST:
  1805  				biggen(l, r, Z, 0, optab[B0c], args);
  1806  				break;
  1807  			case WHARD:
  1808  				reglcgen(&nod2, r, Z);
  1809  				r = &nod2;
  1810  				/* fall thru */
  1811  			case WADDR:
  1812  				biggen(l, r, Z, 0, binoptmp, args);
  1813  				if(ri == WHARD)
  1814  					regfree(r);
  1815  				break;
  1816  			}
  1817  			break;
  1818  		case IMM(1, 0):
  1819  			if(n->op == OSUB) {
  1820  				switch(li) {
  1821  				case WNONE:
  1822  					diag(l, "bad whatof\n");
  1823  					break;
  1824  				case WHARD:
  1825  					reglcgen(&nod2, l, Z);
  1826  					l = &nod2;
  1827  					/* fall thru */
  1828  				case WADDR:
  1829  				case WCONST:
  1830  					biggen(l, r, Z, 0, sub10, args);
  1831  					break;
  1832  				}
  1833  				if(li == WHARD)
  1834  					regfree(l);
  1835  			}
  1836  			else {
  1837  				switch(li) {
  1838  				case WNONE:
  1839  					diag(l, "bad whatof\n");
  1840  					break;
  1841  				case WCONST:
  1842  					biggen(r, l, Z, 0, optab[B0c], args);
  1843  					break;
  1844  				case WHARD:
  1845  					reglcgen(&nod2, l, Z);
  1846  					l = &nod2;
  1847  					/* fall thru */
  1848  				case WADDR:
  1849  					biggen(r, l, Z, 0, binoptmp, args);
  1850  					if(li == WHARD)
  1851  						regfree(l);
  1852  					break;
  1853  				}
  1854  			}
  1855  			break;
  1856  		case IMM(1, 1):
  1857  			switch(WW(li, ri)) {
  1858  			case WW(WCONST, WHARD):
  1859  				if(r->op == ONAME && n->op == OAND && reduxv(l))
  1860  					ri = WADDR;
  1861  				break;
  1862  			case WW(WHARD, WCONST):
  1863  				if(l->op == ONAME && n->op == OAND && reduxv(r))
  1864  					li = WADDR;
  1865  				break;
  1866  			}
  1867  			if(li == WHARD) {
  1868  				reglcgen(&nod3, l, Z);
  1869  				l = &nod3;
  1870  			}
  1871  			if(ri == WHARD) {
  1872  				reglcgen(&nod2, r, Z);
  1873  				r = &nod2;
  1874  			}
  1875  			d = regpair(nn, n);
  1876  			instpair(d, Z);
  1877  			switch(WW(li, ri)) {
  1878  			case WW(WCONST, WADDR):
  1879  			case WW(WCONST, WHARD):
  1880  				biggen(l, r, d, 0, optab[Bca], args);
  1881  				break;
  1882  
  1883  			case WW(WADDR, WCONST):
  1884  			case WW(WHARD, WCONST):
  1885  				biggen(l, r, d, 0, optab[Bac], args);
  1886  				break;
  1887  
  1888  			case WW(WADDR, WADDR):
  1889  			case WW(WADDR, WHARD):
  1890  			case WW(WHARD, WADDR):
  1891  			case WW(WHARD, WHARD):
  1892  				biggen(l, r, d, 0, binop11, args);
  1893  				break;
  1894  
  1895  			default:
  1896  				diag(r, "bad whatof pair %d %d\n", li, ri);
  1897  				break;
  1898  			}
  1899  			if(li == WHARD)
  1900  				regfree(l);
  1901  			if(ri == WHARD)
  1902  				regfree(r);
  1903  			break;
  1904  		}
  1905  
  1906  		nn->type = dt;
  1907  
  1908  		if(d != Z)
  1909  			goto finished;
  1910  
  1911  		switch(lri) {
  1912  		case IMM(0, 0):
  1913  			freepair(r);
  1914  			/* fall thru */;
  1915  		case IMM(0, 1):
  1916  			if(!dr)
  1917  				storepair(l, nn, 1);
  1918  			break;
  1919  		case IMM(1, 0):
  1920  			if(!dr)
  1921  				storepair(r, nn, 1);
  1922  			break;
  1923  		case IMM(1, 1):
  1924  			break;
  1925  		}
  1926  		return 1;
  1927  
  1928  	shift:
  1929  		c = Z;
  1930  
  1931  		/* evaluate hard subexps, stealing nn if possible. */
  1932  		/* must also secure CX.  not as many optims as binop. */
  1933  		switch(lri) {
  1934  		case IMM(0, 0):
  1935  		imm00:
  1936  			if(l->complex + 1 > r->complex) {
  1937  				if(dr)
  1938  					t = nn;
  1939  				else
  1940  					t = regpair(Z, l);
  1941  				sugen(l, t, 8);
  1942  				l = t;
  1943  				t = &nod1;
  1944  				c = snarfreg(l, t, D_CX, r, &nod2);
  1945  				cgen(r, t);
  1946  				r = t;
  1947  			}
  1948  			else {
  1949  				t = &nod1;
  1950  				c = snarfreg(nn, t, D_CX, r, &nod2);
  1951  				cgen(r, t);
  1952  				r = t;
  1953  				if(dr)
  1954  					t = nn;
  1955  				else
  1956  					t = regpair(Z, l);
  1957  				sugen(l, t, 8);
  1958  				l = t;
  1959  			}
  1960  			break;
  1961  		case IMM(0, 1):
  1962  		imm01:
  1963  			if(ri != WCONST) {
  1964  				lri = IMM(0, 0);
  1965  				goto imm00;
  1966  			}
  1967  			if(dr)
  1968  				t = nn;
  1969  			else
  1970  				t = regpair(Z, n);
  1971  			sugen(l, t, 8);
  1972  			l = t;
  1973  			break;
  1974  		case IMM(1, 0):
  1975  		imm10:
  1976  			if(li != WCONST) {
  1977  				lri = IMM(0, 0);
  1978  				goto imm00;
  1979  			}
  1980  			t = &nod1;
  1981  			c = snarfreg(nn, t, D_CX, r, &nod2);
  1982  			cgen(r, t);
  1983  			r = t;
  1984  			break;
  1985  		case IMM(1, 1):
  1986  			if(ri != WCONST) {
  1987  				lri = IMM(1, 0);
  1988  				goto imm10;
  1989  			}
  1990  			if(li == WHARD) {
  1991  				lri = IMM(0, 1);
  1992  				goto imm01;
  1993  			}
  1994  			break;
  1995  		}
  1996  
  1997  		d = Z;
  1998  
  1999  		switch(lri) {
  2000  		case IMM(0, 0):
  2001  			biggen(l, r, Z, 0, optab[S00], args);
  2002  			break;
  2003  		case IMM(0, 1):
  2004  			switch(ri) {
  2005  			case WNONE:
  2006  			case WADDR:
  2007  			case WHARD:
  2008  				diag(r, "bad whatof\n");
  2009  				break;
  2010  			case WCONST:
  2011  				m = r->vconst & 63;
  2012  				s = nodconst(m);
  2013  				if(m < 32)
  2014  					cp = optab[Sc0];
  2015  				else if(m == 32)
  2016  					cp = optab[Sc1];
  2017  				else
  2018  					cp = optab[Sc2];
  2019  				biggen(l, s, Z, 0, cp, args);
  2020  				break;
  2021  			}
  2022  			break;
  2023  		case IMM(1, 0):
  2024  			/* left is const */
  2025  			d = regpair(nn, n);
  2026  			instpair(d, Z);
  2027  			biggen(l, r, d, 0, optab[S10], args);
  2028  			regfree(r);
  2029  			break;
  2030  		case IMM(1, 1):
  2031  			d = regpair(nn, n);
  2032  			instpair(d, Z);
  2033  			switch(WW(li, ri)) {
  2034  			case WW(WADDR, WCONST):
  2035  				m = r->vconst & 63;
  2036  				s = nodconst(m);
  2037  				if(m < 32) {
  2038  					loadpair(l, d);
  2039  					l = d;
  2040  					cp = optab[Sc0];
  2041  				}
  2042  				else if(m == 32)
  2043  					cp = optab[Sac3];
  2044  				else
  2045  					cp = optab[Sac4];
  2046  				biggen(l, s, d, 0, cp, args);
  2047  				break;
  2048  
  2049  			default:
  2050  				diag(r, "bad whatof pair %d %d\n", li, ri);
  2051  				break;
  2052  			}
  2053  			break;
  2054  		}
  2055  
  2056  		if(c != Z) {
  2057  			gins(AMOVL, c, r);
  2058  			regfree(c);
  2059  		}
  2060  
  2061  		if(d != Z)
  2062  			goto finished;
  2063  
  2064  		switch(lri) {
  2065  		case IMM(0, 0):
  2066  			regfree(r);
  2067  			/* fall thru */
  2068  		case IMM(0, 1):
  2069  			if(!dr)
  2070  				storepair(l, nn, 1);
  2071  			break;
  2072  		case IMM(1, 0):
  2073  			regfree(r);
  2074  			break;
  2075  		case IMM(1, 1):
  2076  			break;
  2077  		}
  2078  		return 1;
  2079  
  2080  	cmp:
  2081  		op = n->op;
  2082  		/* evaluate hard subexps */
  2083  		switch(lri) {
  2084  		case IMM(0, 0):
  2085  			if(l->complex > r->complex) {
  2086  				t = regpair(Z, l);
  2087  				sugen(l, t, 8);
  2088  				l = t;
  2089  				t = regpair(Z, r);
  2090  				sugen(r, t, 8);
  2091  				r = t;
  2092  			}
  2093  			else {
  2094  				t = regpair(Z, r);
  2095  				sugen(r, t, 8);
  2096  				r = t;
  2097  				t = regpair(Z, l);
  2098  				sugen(l, t, 8);
  2099  				l = t;
  2100  			}
  2101  			break;
  2102  		case IMM(1, 0):
  2103  			t = r;
  2104  			r = l;
  2105  			l = t;
  2106  			ri = li;
  2107  			op = invrel[relindex(op)];
  2108  			/* fall thru */
  2109  		case IMM(0, 1):
  2110  			t = regpair(Z, l);
  2111  			sugen(l, t, 8);
  2112  			l = t;
  2113  			break;
  2114  		case IMM(1, 1):
  2115  			break;
  2116  		}
  2117  
  2118  		true = 1;
  2119  		optab = cmptab;
  2120  		switch(op) {
  2121  		case OEQ:
  2122  			optab = NEtab;
  2123  			true = 0;
  2124  			break;
  2125  		case ONE:
  2126  			optab = NEtab;
  2127  			break;
  2128  		case OLE:
  2129  			args = GTargs;
  2130  			true = 0;
  2131  			break;
  2132  		case OGT:
  2133  			args = GTargs;
  2134  			break;
  2135  		case OLS:
  2136  			args = HIargs;
  2137  			true = 0;
  2138  			break;
  2139  		case OHI:
  2140  			args = HIargs;
  2141  			break;
  2142  		case OLT:
  2143  			args = GEargs;
  2144  			true = 0;
  2145  			break;
  2146  		case OGE:
  2147  			args = GEargs;
  2148  			break;
  2149  		case OLO:
  2150  			args = HSargs;
  2151  			true = 0;
  2152  			break;
  2153  		case OHS:
  2154  			args = HSargs;
  2155  			break;
  2156  		default:
  2157  			diag(n, "bad cmp\n");
  2158  			SET(optab);
  2159  		}
  2160  
  2161  		switch(lri) {
  2162  		case IMM(0, 0):
  2163  			biggen(l, r, Z, true, optab[T0i], args);
  2164  			break;
  2165  		case IMM(0, 1):
  2166  		case IMM(1, 0):
  2167  			switch(ri) {
  2168  			case WNONE:
  2169  				diag(l, "bad whatof\n");
  2170  				break;
  2171  			case WCONST:
  2172  				biggen(l, r, Z, true, optab[T0i], args);
  2173  				break;
  2174  			case WHARD:
  2175  				reglcgen(&nod2, r, Z);
  2176  				r = &nod2;
  2177  				/* fall thru */
  2178  			case WADDR:
  2179  				biggen(l, r, Z, true, optab[T0i], args);
  2180  				if(ri == WHARD)
  2181  					regfree(r);
  2182  				break;
  2183  			}
  2184  			break;
  2185  		case IMM(1, 1):
  2186  			if(li == WHARD) {
  2187  				reglcgen(&nod3, l, Z);
  2188  				l = &nod3;
  2189  			}
  2190  			if(ri == WHARD) {
  2191  				reglcgen(&nod2, r, Z);
  2192  				r = &nod2;
  2193  			}
  2194  			biggen(l, r, Z, true, optab[Tii], args);
  2195  			if(li == WHARD)
  2196  				regfree(l);
  2197  			if(ri == WHARD)
  2198  				regfree(r);
  2199  			break;
  2200  		}
  2201  
  2202  		switch(lri) {
  2203  		case IMM(0, 0):
  2204  			freepair(r);
  2205  			/* fall thru */;
  2206  		case IMM(0, 1):
  2207  		case IMM(1, 0):
  2208  			freepair(l);
  2209  			break;
  2210  		case IMM(1, 1):
  2211  			break;
  2212  		}
  2213  		return 1;
  2214  
  2215  	case OASMUL:
  2216  	case OASLMUL:
  2217  		m = 0;
  2218  		goto mulop;
  2219  
  2220  	case OMUL:
  2221  	case OLMUL:
  2222  		m = 1;
  2223  		goto mulop;
  2224  
  2225  	mulop:
  2226  		dr = nn != Z && nn->op == OREGPAIR;
  2227  		l = vfunc(n->left, nn);
  2228  		r = vfunc(n->right, nn);
  2229  		if(r->op != OCONST) {
  2230  			if(l->complex > r->complex) {
  2231  				if(m) {
  2232  					t = l;
  2233  					l = r;
  2234  					r = t;
  2235  				}
  2236  				else if(!vaddr(l, 1)) {
  2237  					reglcgen(&nod5, l, Z);
  2238  					l = &nod5;
  2239  					evacaxdx(l);
  2240  				}
  2241  			}
  2242  			t = regpair(Z, n);
  2243  			sugen(r, t, 8);
  2244  			r = t;
  2245  			evacaxdx(r->left);
  2246  			evacaxdx(r->right);
  2247  			if(l->complex <= r->complex && !m && !vaddr(l, 1)) {
  2248  				reglcgen(&nod5, l, Z);
  2249  				l = &nod5;
  2250  				evacaxdx(l);
  2251  			}
  2252  		}
  2253  		if(dr)
  2254  			t = nn;
  2255  		else
  2256  			t = regpair(Z, n);
  2257  		c = Z;
  2258  		d = Z;
  2259  		if(!nodreg(&nod1, t->left, D_AX)) {
  2260  			if(t->left->reg != D_AX){
  2261  				t->left->reg = D_AX;
  2262  				reg[D_AX]++;
  2263  			}else if(reg[D_AX] == 0)
  2264  				fatal(Z, "vlong mul AX botch");
  2265  		}
  2266  		if(!nodreg(&nod2, t->right, D_DX)) {
  2267  			if(t->right->reg != D_DX){
  2268  				t->right->reg = D_DX;
  2269  				reg[D_DX]++;
  2270  			}else if(reg[D_DX] == 0)
  2271  				fatal(Z, "vlong mul DX botch");
  2272  		}
  2273  		if(m)
  2274  			sugen(l, t, 8);
  2275  		else
  2276  			loadpair(l, t);
  2277  		if(t->left->reg != D_AX) {
  2278  			c = &nod3;
  2279  			regsalloc(c, t->left);
  2280  			gmove(&nod1, c);
  2281  			gmove(t->left, &nod1);
  2282  			zapreg(t->left);
  2283  		}
  2284  		if(t->right->reg != D_DX) {
  2285  			d = &nod4;
  2286  			regsalloc(d, t->right);
  2287  			gmove(&nod2, d);
  2288  			gmove(t->right, &nod2);
  2289  			zapreg(t->right);
  2290  		}
  2291  		if(c != Z || d != Z) {
  2292  			s = regpair(Z, n);
  2293  			s->left = &nod1;
  2294  			s->right = &nod2;
  2295  		}
  2296  		else
  2297  			s = t;
  2298  		if(r->op == OCONST) {
  2299  			if(hi64v(r) == 0)
  2300  				biggen(s, r, Z, 0, mulc32, nil);
  2301  			else
  2302  				biggen(s, r, Z, 0, mulc64, nil);
  2303  		}
  2304  		else
  2305  			biggen(s, r, Z, 0, mull, nil);
  2306  		instpair(t, Z);
  2307  		if(c != Z) {
  2308  			gmove(&nod1, t->left);
  2309  			gmove(&nod3, &nod1);
  2310  		}
  2311  		if(d != Z) {
  2312  			gmove(&nod2, t->right);
  2313  			gmove(&nod4, &nod2);
  2314  		}
  2315  		if(r->op == OREGPAIR)
  2316  			freepair(r);
  2317  		if(!m)
  2318  			storepair(t, l, 0);
  2319  		if(l == &nod5)
  2320  			regfree(l);
  2321  		if(!dr) {
  2322  			if(nn != Z)
  2323  				storepair(t, nn, 1);
  2324  			else
  2325  				freepair(t);
  2326  		}
  2327  		return 1;
  2328  
  2329  	case OASADD:
  2330  		args = ADDargs;
  2331  		goto vasop;
  2332  	case OASAND:
  2333  		args = ANDargs;
  2334  		goto vasop;
  2335  	case OASOR:
  2336  		args = ORargs;
  2337  		goto vasop;
  2338  	case OASSUB:
  2339  		args = SUBargs;
  2340  		goto vasop;
  2341  	case OASXOR:
  2342  		args = XORargs;
  2343  		goto vasop;
  2344  
  2345  	vasop:
  2346  		l = n->left;
  2347  		r = n->right;
  2348  		dr = nn != Z && nn->op == OREGPAIR;
  2349  		m = 0;
  2350  		if(l->complex > r->complex) {
  2351  			if(!vaddr(l, 1)) {
  2352  				reglcgen(&nod1, l, Z);
  2353  				l = &nod1;
  2354  			}
  2355  			if(!vaddr(r, 1) || nn != Z || r->op == OCONST) {
  2356  				if(dr)
  2357  					t = nn;
  2358  				else
  2359  					t = regpair(Z, r);
  2360  				sugen(r, t, 8);
  2361  				r = t;
  2362  				m = 1;
  2363  			}
  2364  		}
  2365  		else {
  2366  			if(!vaddr(r, 1) || nn != Z || r->op == OCONST) {
  2367  				if(dr)
  2368  					t = nn;
  2369  				else
  2370  					t = regpair(Z, r);
  2371  				sugen(r, t, 8);
  2372  				r = t;
  2373  				m = 1;
  2374  			}
  2375  			if(!vaddr(l, 1)) {
  2376  				reglcgen(&nod1, l, Z);
  2377  				l = &nod1;
  2378  			}
  2379  		}
  2380  		if(nn != Z) {
  2381  			if(n->op == OASSUB)
  2382  				biggen(l, r, Z, 0, sub10, args);
  2383  			else
  2384  				biggen(r, l, Z, 0, binoptmp, args);
  2385  			storepair(r, l, 0);
  2386  		}
  2387  		else {
  2388  			if(m)
  2389  				biggen(l, r, Z, 0, binop00, args);
  2390  			else
  2391  				biggen(l, r, Z, 0, binoptmp, args);
  2392  		}
  2393  		if(l == &nod1)
  2394  			regfree(&nod1);
  2395  		if(m) {
  2396  			if(nn == Z)
  2397  				freepair(r);
  2398  			else if(!dr)
  2399  				storepair(r, nn, 1);
  2400  		}
  2401  		return 1;
  2402  
  2403  	case OASASHL:
  2404  		args = nil;
  2405  		optab = asshlltab;
  2406  		goto assh;
  2407  	case OASLSHR:
  2408  		args = shrlargs;
  2409  		optab = asshrltab;
  2410  		goto assh;
  2411  	case OASASHR:
  2412  		args = sarlargs;
  2413  		optab = asshrltab;
  2414  		goto assh;
  2415  
  2416  	assh:
  2417  		c = Z;
  2418  		l = n->left;
  2419  		r = n->right;
  2420  		if(r->op == OCONST) {
  2421  			m = r->vconst & 63;
  2422  			if(m < 32)
  2423  				m = SAclo;
  2424  			else if(m == 32)
  2425  				m = SAc32;
  2426  			else
  2427  				m = SAchi;
  2428  		}
  2429  		else
  2430  			m = SAgen;
  2431  		if(l->complex > r->complex) {
  2432  			if(!vaddr(l, 0)) {
  2433  				reglcgen(&nod1, l, Z);
  2434  				l = &nod1;
  2435  			}
  2436  			if(m == SAgen) {
  2437  				t = &nod2;
  2438  				if(l->reg == D_CX) {
  2439  					regalloc(t, r, Z);
  2440  					gmove(l, t);
  2441  					l->reg = t->reg;
  2442  					t->reg = D_CX;
  2443  				}
  2444  				else
  2445  					c = snarfreg(nn, t, D_CX, r, &nod3);
  2446  				cgen(r, t);
  2447  				r = t;
  2448  			}
  2449  		}
  2450  		else {
  2451  			if(m == SAgen) {
  2452  				t = &nod2;
  2453  				c = snarfreg(nn, t, D_CX, r, &nod3);
  2454  				cgen(r, t);
  2455  				r = t;
  2456  			}
  2457  			if(!vaddr(l, 0)) {
  2458  				reglcgen(&nod1, l, Z);
  2459  				l = &nod1;
  2460  			}
  2461  		}
  2462  
  2463  		if(nn != Z) {
  2464  			m += SAdgen - SAgen;
  2465  			d = regpair(nn, n);
  2466  			instpair(d, Z);
  2467  			biggen(l, r, d, 0, optab[m], args);
  2468  			if(l == &nod1) {
  2469  				regfree(&nod1);
  2470  				l = Z;
  2471  			}
  2472  			if(r == &nod2 && c == Z) {
  2473  				regfree(&nod2);
  2474  				r = Z;
  2475  			}
  2476  			if(d != nn)
  2477  				storepair(d, nn, 1);
  2478  		}
  2479  		else
  2480  			biggen(l, r, Z, 0, optab[m], args);
  2481  
  2482  		if(c != Z) {
  2483  			gins(AMOVL, c, r);
  2484  			regfree(c);
  2485  		}
  2486  		if(l == &nod1)
  2487  			regfree(&nod1);
  2488  		if(r == &nod2)
  2489  			regfree(&nod2);
  2490  		return 1;
  2491  
  2492  	case OPOSTINC:
  2493  		args = ADDargs;
  2494  		cp = incdecpost;
  2495  		goto vinc;
  2496  	case OPOSTDEC:
  2497  		args = SUBargs;
  2498  		cp = incdecpost;
  2499  		goto vinc;
  2500  	case OPREINC:
  2501  		args = ADDargs;
  2502  		cp = incdecpre;
  2503  		goto vinc;
  2504  	case OPREDEC:
  2505  		args = SUBargs;
  2506  		cp = incdecpre;
  2507  		goto vinc;
  2508  
  2509  	vinc:
  2510  		l = n->left;
  2511  		if(!vaddr(l, 1)) {
  2512  			reglcgen(&nod1, l, Z);
  2513  			l = &nod1;
  2514  		}
  2515  		
  2516  		if(nn != Z) {
  2517  			d = regpair(nn, n);
  2518  			instpair(d, Z);
  2519  			biggen(l, Z, d, 0, cp, args);
  2520  			if(l == &nod1) {
  2521  				regfree(&nod1);
  2522  				l = Z;
  2523  			}
  2524  			if(d != nn)
  2525  				storepair(d, nn, 1);
  2526  		}
  2527  		else
  2528  			biggen(l, Z, Z, 0, incdec, args);
  2529  
  2530  		if(l == &nod1)
  2531  			regfree(&nod1);
  2532  		return 1;
  2533  
  2534  	case OCAST:
  2535  		l = n->left;
  2536  		if(typev[l->type->etype]) {
  2537  			if(!vaddr(l, 1)) {
  2538  				if(l->complex + 1 > nn->complex) {
  2539  					d = regpair(Z, l);
  2540  					sugen(l, d, 8);
  2541  					if(!vaddr(nn, 1)) {
  2542  						reglcgen(&nod1, nn, Z);
  2543  						r = &nod1;
  2544  					}
  2545  					else
  2546  						r = nn;
  2547  				}
  2548  				else {
  2549  					if(!vaddr(nn, 1)) {
  2550  						reglcgen(&nod1, nn, Z);
  2551  						r = &nod1;
  2552  					}
  2553  					else
  2554  						r = nn;
  2555  					d = regpair(Z, l);
  2556  					sugen(l, d, 8);
  2557  				}
  2558  //				d->left->type = r->type;
  2559  				d->left->type = types[TLONG];
  2560  				gmove(d->left, r);
  2561  				freepair(d);
  2562  			}
  2563  			else {
  2564  				if(nn->op != OREGISTER && !vaddr(nn, 1)) {
  2565  					reglcgen(&nod1, nn, Z);
  2566  					r = &nod1;
  2567  				}
  2568  				else
  2569  					r = nn;
  2570  //				l->type = r->type;
  2571  				l->type = types[TLONG];
  2572  				gmove(l, r);
  2573  			}
  2574  			if(r != nn)
  2575  				regfree(r);
  2576  		}
  2577  		else {
  2578  			if(typeu[l->type->etype] || cond(l->op))
  2579  				si = TUNSIGNED;
  2580  			else
  2581  				si = TSIGNED;
  2582  			regalloc(&nod1, l, Z);
  2583  			cgen(l, &nod1);
  2584  			if(nn->op == OREGPAIR) {
  2585  				m = instpair(nn, &nod1);
  2586  				biggen(&nod1, Z, nn, si == TSIGNED, castrp, nil);
  2587  			}
  2588  			else {
  2589  				m = 0;
  2590  				if(!vaddr(nn, si != TSIGNED)) {
  2591  					dt = nn->type;
  2592  					nn->type = types[TLONG];
  2593  					reglcgen(&nod2, nn, Z);
  2594  					nn->type = dt;
  2595  					nn = &nod2;
  2596  				}
  2597  				dt = nn->type;
  2598  				nn->type = types[TLONG];
  2599  				biggen(&nod1, Z, nn, si == TSIGNED, castrpa, nil);
  2600  				nn->type = dt;
  2601  				if(nn == &nod2)
  2602  					regfree(&nod2);
  2603  			}
  2604  			if(!m)
  2605  				regfree(&nod1);
  2606  		}
  2607  		return 1;
  2608  
  2609  	default:
  2610  		if(n->op == OREGPAIR) {
  2611  			storepair(n, nn, 1);
  2612  			return 1;
  2613  		}
  2614  		if(nn->op == OREGPAIR) {
  2615  			loadpair(n, nn);
  2616  			return 1;
  2617  		}
  2618  		return 0;
  2619  	}
  2620  finished:
  2621  	if(d != nn)
  2622  		storepair(d, nn, 1);
  2623  	return 1;
  2624  }
  2625  
  2626  void
  2627  testv(Node *n, int true)
  2628  {
  2629  	Type *t;
  2630  	Node *nn, nod;
  2631  
  2632  	switch(n->op) {
  2633  	case OINDREG:
  2634  	case ONAME:
  2635  		biggen(n, Z, Z, true, testi, nil);
  2636  		break;
  2637  
  2638  	default:
  2639  		n = vfunc(n, n);
  2640  		if(n->addable >= INDEXED) {
  2641  			t = n->type;
  2642  			n->type = types[TLONG];
  2643  			reglcgen(&nod, n, Z);
  2644  			n->type = t;
  2645  			n = &nod;
  2646  			biggen(n, Z, Z, true, testi, nil);
  2647  			if(n == &nod)
  2648  				regfree(n);
  2649  		}
  2650  		else {
  2651  			nn = regpair(Z, n);
  2652  			sugen(n, nn, 8);
  2653  			biggen(nn, Z, Z, true, testi, nil);
  2654  			freepair(nn);
  2655  		}
  2656  	}
  2657  }