PageRenderTime 970ms CodeModel.GetById 100ms app.highlight 764ms RepoModel.GetById 17ms app.codeStats 3ms

/src/cmd/8c/cgen64.c

https://github.com/SDpower/golang
C | 2657 lines | 2327 code | 196 blank | 134 comment | 359 complexity | b0dc6bdf1fefedeb474bd7830107f499 MD5 | raw file
   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
  33void
  34zeroregm(Node *n)
  35{
  36	gins(AMOVL, nodconst(0), n);
  37}
  38
  39/* do we need to load the address of a vlong? */
  40int
  41vaddr(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
  57int32
  58hi64v(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
  66int32
  67lo64v(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
  75Node *
  76hi64(Node *n)
  77{
  78	return nodconst(hi64v(n));
  79}
  80
  81Node *
  82lo64(Node *n)
  83{
  84	return nodconst(lo64v(n));
  85}
  86
  87static Node *
  88anonreg(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
  98static Node *
  99regpair(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
 113static void
 114evacaxdx(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 */
 137static int
 138instpair(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
 156static void
 157zapreg(Node *n)
 158{
 159	if(n->reg != D_NONE) {
 160		regfree(n);
 161		n->reg = D_NONE;
 162	}
 163}
 164
 165static void
 166freepair(Node *n)
 167{
 168	regfree(n->left);
 169	regfree(n->right);
 170}
 171
 172/* n is not OREGPAIR, nn is */
 173void
 174loadpair(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 */
 202static void
 203storepair(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
 221enum
 222{
 223/* 4 only, see WW */
 224	WNONE	= 0,
 225	WCONST,
 226	WADDR,
 227	WHARD,
 228};
 229
 230static int
 231whatof(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 */
 239static int
 240reduxv(Node *n)
 241{
 242	return lo64v(n) == 0 || hi64v(n) == 0;
 243}
 244
 245int
 246cond(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 */
 273static Node *
 274vfunc(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 */
 289static int
 290getreg(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
 306static Node *
 307snarfreg(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
 321enum
 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
 454static 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 */
 466static 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 */
 478static 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 */
 485static 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 */
 492static 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 */
 500static 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 */
 507static 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 */
 515static 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
 528static 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 */
 540static 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 */
 554static 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 */
 561static 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 */
 570static 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 */
 580static 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 */
 590static 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 */
 601static 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
 618static 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 */
 630static 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 */
 649static 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 */
 662static 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 */
 672static 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 */
 683static 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 */
 702static 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 */
 714static 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 */
 724static 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
 734static 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 */
 747static 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 */
 768static 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 */
 781static 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 */
 793static 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 */
 806static 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 */
 826static 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 */
 838static 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 */
 850static 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
 864static uchar	(*asshrltab[])[VLEN] =
 865{
 866	asshrlgen,
 867	asshrlclo,
 868	asshrlc32,
 869	asshrlchi,
 870	asdshrlgen,
 871	asdshrlclo,
 872	asdshrlc32,
 873	asdshrlchi,
 874};
 875
 876static uchar	shrlargs[]	= { ASHRL, 1 };
 877static uchar	sarlargs[]	= { ASARL, 0 };
 878
 879/* ++ -- */
 880static uchar	incdec[][VLEN] =
 881{
 882	{Vinsx, Bop0, C01, O_l_lo},
 883	{Vinsx, Bop1, C00, O_l_hi, Vend},
 884};
 885
 886/* ++ -- *p */
 887static 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 ++ -- */
 898static 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 */
 907static 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 */
 915static 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 */
 925static 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 */
 934static 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 */
 943static 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 */
 953static 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 */
 961static 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 */
 971static 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 */
 982static 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 */
 994static 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 */
1004static 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 */
1014static 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 */
1025static 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 */
1035static 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
1046static uchar	ADDargs[]	= { AADDL, AADCL };
1047static uchar	ANDargs[]	= { AANDL, AANDL };
1048static uchar	ORargs[]	= { AORL, AORL };
1049static uchar	SUBargs[]	= { ASUBL, ASBBL };
1050static uchar	XORargs[]	= { AXORL, AXORL };
1051
1052static uchar	(*ADDtab[])[VLEN] =
1053{
1054	add0c, addca, addac,
1055};
1056
1057static uchar	(*ANDtab[])[VLEN] =
1058{
1059	and0c, andca, andac,
1060};
1061
1062static uchar	(*ORtab[])[VLEN] =
1063{
1064	or0c, orca, orac,
1065};
1066
1067static uchar	(*SUBtab[])[VLEN] =
1068{
1069	add0c, subca, addac,
1070};
1071
1072/* mul of const32 */
1073static 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 */
1088static 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 */
1107static 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 */
1126static 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 */
1136static 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
1148static 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
1159static 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
1172static 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
1186static 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
1202static uchar	(*NEtab[])[VLEN] =
1203{
1204	netab0i, netabii,
1205};
1206
1207static uchar	(*cmptab[])[VLEN] =
1208{
1209	cmptab0i, cmptabii,
1210};
1211
1212static uchar	GEargs[]	= { OGT, OHS };
1213static uchar	GTargs[]	= { OGT, OHI };
1214static uchar	HIargs[]	= { OHI, OHI };
1215static uchar	HSargs[]	= { OHI, OHS };
1216
1217/* Big Generator */
1218static void
1219biggen(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	}
1582out:
1583	if(lo)
1584		l->xoffset -= lo;
1585	if(ro)
1586		r->xoffset -= ro;
1587	if(to)
1588		t->xoffset -= to;
1589}
1590
1591int
1592cgen64(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
1712twoop:
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	}
2620finished:
2621	if(d != nn)
2622		storepair(d, nn, 1);
2623	return 1;
2624}
2625
2626void
2627testv(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}