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

/src/cmd/8c/cgen64.c

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