1 #include "gc.h"
2
3 void
zeroregm(Node * n)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
vaddr(Node * n,int a)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
hi64v(Node * n)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
lo64v(Node * n)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 *
hi64(Node * n)46 hi64(Node *n)
47 {
48 return nodconst(hi64v(n));
49 }
50
51 Node *
lo64(Node * n)52 lo64(Node *n)
53 {
54 return nodconst(lo64v(n));
55 }
56
57 static Node *
anonreg(void)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 *
regpair(Node * n,Node * t)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
evacaxdx(Node * r)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
instpair(Node * n,Node * l)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
zapreg(Node * n)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
freepair(Node * n)137 freepair(Node *n)
138 {
139 regfree(n->left);
140 regfree(n->right);
141 }
142
143 /* n is not OREGPAIR, nn is */
144 void
loadpair(Node * n,Node * nn)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
storepair(Node * n,Node * nn,int f)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
whatof(Node * n,int a)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
reduxv(Node * n)211 reduxv(Node *n)
212 {
213 return lo64v(n) == 0 || hi64v(n) == 0;
214 }
215
216 int
cond(int op)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 *
vfunc(Node * n,Node * nn)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
getreg(Node ** np,Node * t,int r)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 *
snarfreg(Node * n,Node * t,int r,Node * d,Node * c)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
biggen(Node * l,Node * r,Node * t,int true,uchar code[][VLEN],uchar * a)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
cgen64(Node * n,Node * nn)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
testv(Node * n,int true)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 }
2655