Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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