PageRenderTime 62ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/utils/8c/cgen64.c

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