PageRenderTime 72ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/utils/8c/cgen64.c

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