PageRenderTime 37ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/utils/0c/txt.c

https://bitbucket.org/floren/inferno/
C | 1483 lines | 1365 code | 104 blank | 14 comment | 392 complexity | 98b6f05064d36dcf02bf74d6b2387e16 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. ginit(void)
  4. {
  5. int i;
  6. Type *t;
  7. thechar = '0';
  8. thestring = "spim";
  9. exregoffset = REGEXT;
  10. exfregoffset = FREGEXT;
  11. listinit();
  12. nstring = 0;
  13. mnstring = 0;
  14. nrathole = 0;
  15. pc = 0;
  16. breakpc = -1;
  17. continpc = -1;
  18. cases = C;
  19. firstp = P;
  20. lastp = P;
  21. tfield = types[TLONG];
  22. zprog.link = P;
  23. zprog.as = AGOK;
  24. zprog.reg = NREG;
  25. zprog.from.type = D_NONE;
  26. zprog.from.name = D_NONE;
  27. zprog.from.reg = NREG;
  28. zprog.to = zprog.from;
  29. regnode.op = OREGISTER;
  30. regnode.class = CEXREG;
  31. regnode.reg = REGTMP;
  32. regnode.complex = 0;
  33. regnode.addable = 11;
  34. regnode.type = types[TLONG];
  35. constnode.op = OCONST;
  36. constnode.class = CXXX;
  37. constnode.complex = 0;
  38. constnode.addable = 20;
  39. constnode.type = types[TLONG];
  40. fconstnode.op = OCONST;
  41. fconstnode.class = CXXX;
  42. fconstnode.complex = 0;
  43. fconstnode.addable = 20;
  44. fconstnode.type = types[TDOUBLE];
  45. nodsafe = new(ONAME, Z, Z);
  46. nodsafe->sym = slookup(".safe");
  47. nodsafe->type = types[TINT];
  48. nodsafe->etype = types[TINT]->etype;
  49. nodsafe->class = CAUTO;
  50. complex(nodsafe);
  51. t = typ(TARRAY, types[TCHAR]);
  52. symrathole = slookup(".rathole");
  53. symrathole->class = CGLOBL;
  54. symrathole->type = t;
  55. nodrat = new(ONAME, Z, Z);
  56. nodrat->sym = symrathole;
  57. nodrat->type = types[TIND];
  58. nodrat->etype = TVOID;
  59. nodrat->class = CGLOBL;
  60. complex(nodrat);
  61. nodrat->type = t;
  62. nodret = new(ONAME, Z, Z);
  63. nodret->sym = slookup(".ret");
  64. nodret->type = types[TIND];
  65. nodret->etype = TIND;
  66. nodret->class = CPARAM;
  67. nodret = new(OIND, nodret, Z);
  68. complex(nodret);
  69. for(i=0; i<nelem(reg); i++) {
  70. reg[i] = 0;
  71. if(i == REGZERO ||
  72. (i >= NREG && ((i-NREG)&1)))
  73. reg[i] = 1;
  74. }
  75. }
  76. void
  77. gclean(void)
  78. {
  79. int i;
  80. Sym *s;
  81. for(i=0; i<NREG; i++)
  82. if(i != REGZERO)
  83. if(reg[i])
  84. diag(Z, "reg %d left allocated", i);
  85. for(i=NREG; i<NREG+NREG; i+=2)
  86. if(reg[i])
  87. diag(Z, "freg %d left allocated", i-NREG);
  88. while(mnstring)
  89. outstring("", 1L);
  90. symstring->type->width = nstring;
  91. symrathole->type->width = nrathole;
  92. for(i=0; i<NHASH; i++)
  93. for(s = hash[i]; s != S; s = s->link) {
  94. if(s->type == T)
  95. continue;
  96. if(s->type->width == 0)
  97. continue;
  98. if(s->class != CGLOBL && s->class != CSTATIC)
  99. continue;
  100. if(s->type == types[TENUM])
  101. continue;
  102. gpseudo(AGLOBL, s, nodconst(s->type->width));
  103. }
  104. nextpc();
  105. p->as = AEND;
  106. outcode();
  107. }
  108. void
  109. nextpc(void)
  110. {
  111. p = alloc(sizeof(*p));
  112. *p = zprog;
  113. p->lineno = nearln;
  114. pc++;
  115. if(firstp == P) {
  116. firstp = p;
  117. lastp = p;
  118. return;
  119. }
  120. lastp->link = p;
  121. lastp = p;
  122. }
  123. void
  124. gargs(Node *n, Node *tn1, Node *tn2)
  125. {
  126. long regs;
  127. Node fnxargs[20], *fnxp;
  128. regs = cursafe;
  129. fnxp = fnxargs;
  130. garg1(n, tn1, tn2, 0, &fnxp); /* compile fns to temps */
  131. curarg = 0;
  132. fnxp = fnxargs;
  133. garg1(n, tn1, tn2, 1, &fnxp); /* compile normal args and temps */
  134. cursafe = regs;
  135. }
  136. void
  137. garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
  138. {
  139. Node nod;
  140. if(n == Z)
  141. return;
  142. if(n->op == OLIST) {
  143. garg1(n->left, tn1, tn2, f, fnxp);
  144. garg1(n->right, tn1, tn2, f, fnxp);
  145. return;
  146. }
  147. if(f == 0) {
  148. if(n->complex >= FNX) {
  149. regsalloc(*fnxp, n);
  150. nod = znode;
  151. nod.op = OAS;
  152. nod.left = *fnxp;
  153. nod.right = n;
  154. nod.type = n->type;
  155. cgen(&nod, Z);
  156. (*fnxp)++;
  157. }
  158. return;
  159. }
  160. if(typesu[n->type->etype]) {
  161. regaalloc(tn2, n);
  162. if(n->complex >= FNX) {
  163. sugen(*fnxp, tn2, n->type->width);
  164. (*fnxp)++;
  165. } else
  166. sugen(n, tn2, n->type->width);
  167. return;
  168. }
  169. if(REGARG && curarg == 0 && typechlp[n->type->etype]) {
  170. regaalloc1(tn1, n);
  171. if(n->complex >= FNX) {
  172. cgen(*fnxp, tn1);
  173. (*fnxp)++;
  174. } else
  175. cgen(n, tn1);
  176. return;
  177. }
  178. if(vconst(n) == 0) {
  179. regaalloc(tn2, n);
  180. gopcode(OAS, n, Z, tn2);
  181. return;
  182. }
  183. regalloc(tn1, n, Z);
  184. if(n->complex >= FNX) {
  185. cgen(*fnxp, tn1);
  186. (*fnxp)++;
  187. } else
  188. cgen(n, tn1);
  189. regaalloc(tn2, n);
  190. gopcode(OAS, tn1, Z, tn2);
  191. regfree(tn1);
  192. }
  193. Node*
  194. nodconst(long v)
  195. {
  196. constnode.vconst = v;
  197. return &constnode;
  198. }
  199. Node*
  200. nodfconst(double d)
  201. {
  202. fconstnode.fconst = d;
  203. return &fconstnode;
  204. }
  205. void
  206. nodreg(Node *n, Node *nn, int reg)
  207. {
  208. *n = regnode;
  209. n->reg = reg;
  210. n->type = nn->type;
  211. n->lineno = nn->lineno;
  212. }
  213. void
  214. regret(Node *n, Node *nn)
  215. {
  216. int r;
  217. r = REGRET;
  218. if(typefd[nn->type->etype])
  219. r = FREGRET+NREG;
  220. nodreg(n, nn, r);
  221. reg[r]++;
  222. }
  223. int
  224. tmpreg(void)
  225. {
  226. int i;
  227. for(i=REGRET+1; i<NREG; i++)
  228. if(reg[i] == 0)
  229. return i;
  230. diag(Z, "out of fixed registers");
  231. return 0;
  232. }
  233. void
  234. regalloc(Node *n, Node *tn, Node *o)
  235. {
  236. int i, j;
  237. static int lasti;
  238. switch(tn->type->etype) {
  239. case TCHAR:
  240. case TUCHAR:
  241. case TSHORT:
  242. case TUSHORT:
  243. case TINT:
  244. case TUINT:
  245. case TLONG:
  246. case TULONG:
  247. case TIND:
  248. case TUVLONG:
  249. case TVLONG:
  250. if(o != Z && o->op == OREGISTER) {
  251. i = o->reg;
  252. if(i > 0 && i < NREG)
  253. goto out;
  254. }
  255. j = lasti + REGRET+1;
  256. for(i=REGRET+1; i<NREG; i++) {
  257. if(j >= NREG)
  258. j = REGRET+1;
  259. if(reg[j] == 0) {
  260. i = j;
  261. goto out;
  262. }
  263. j++;
  264. }
  265. diag(tn, "out of fixed registers");
  266. goto err;
  267. case TFLOAT:
  268. case TDOUBLE:
  269. if(o != Z && o->op == OREGISTER) {
  270. i = o->reg;
  271. if(i >= NREG && i < NREG+NREG)
  272. goto out;
  273. }
  274. j = 0*2 + NREG;
  275. for(i=NREG; i<NREG+NREG; i+=2) {
  276. if(j >= NREG+NREG)
  277. j = NREG;
  278. if(reg[j] == 0) {
  279. i = j;
  280. goto out;
  281. }
  282. j += 2;
  283. }
  284. diag(tn, "out of float registers");
  285. goto err;
  286. }
  287. diag(tn, "unknown type in regalloc: %T", tn->type);
  288. err:
  289. i = 0;
  290. out:
  291. if(i)
  292. reg[i]++;
  293. lasti++;
  294. if(lasti >= 5)
  295. lasti = 0;
  296. nodreg(n, tn, i);
  297. }
  298. void
  299. regialloc(Node *n, Node *tn, Node *o)
  300. {
  301. Node nod;
  302. nod = *tn;
  303. nod.type = types[TIND];
  304. regalloc(n, &nod, o);
  305. }
  306. void
  307. regfree(Node *n)
  308. {
  309. int i;
  310. i = 0;
  311. if(n->op != OREGISTER && n->op != OINDREG)
  312. goto err;
  313. i = n->reg;
  314. if(i < 0 || i >= sizeof(reg))
  315. goto err;
  316. if(reg[i] <= 0)
  317. goto err;
  318. reg[i]--;
  319. return;
  320. err:
  321. diag(n, "error in regfree: %d", i);
  322. }
  323. void
  324. regsalloc(Node *n, Node *nn)
  325. {
  326. cursafe = align(cursafe, nn->type, Aaut3);
  327. maxargsafe = maxround(maxargsafe, cursafe+curarg);
  328. *n = *nodsafe;
  329. n->xoffset = -(stkoff + cursafe);
  330. n->type = nn->type;
  331. n->etype = nn->type->etype;
  332. n->lineno = nn->lineno;
  333. }
  334. void
  335. regaalloc1(Node *n, Node *nn)
  336. {
  337. nodreg(n, nn, REGARG);
  338. reg[REGARG]++;
  339. curarg = align(curarg, nn->type, Aarg1);
  340. curarg = align(curarg, nn->type, Aarg2);
  341. maxargsafe = maxround(maxargsafe, cursafe+curarg);
  342. }
  343. void
  344. regaalloc(Node *n, Node *nn)
  345. {
  346. curarg = align(curarg, nn->type, Aarg1);
  347. *n = *nn;
  348. n->op = OINDREG;
  349. n->reg = REGSP;
  350. n->xoffset = curarg + SZ_VLONG;
  351. n->complex = 0;
  352. n->addable = 20;
  353. curarg = align(curarg, nn->type, Aarg2);
  354. maxargsafe = maxround(maxargsafe, cursafe+curarg);
  355. }
  356. void
  357. regind(Node *n, Node *nn)
  358. {
  359. if(n->op != OREGISTER) {
  360. diag(n, "regind not OREGISTER");
  361. return;
  362. }
  363. n->op = OINDREG;
  364. n->type = nn->type;
  365. }
  366. void
  367. raddr(Node *n, Prog *p)
  368. {
  369. Adr a;
  370. naddr(n, &a);
  371. if(a.type == D_CONST && a.offset == 0) {
  372. a.type = D_REG;
  373. a.reg = 0;
  374. }
  375. if(a.type != D_REG && a.type != D_FREG) {
  376. if(n)
  377. diag(n, "bad in raddr: %O", n->op);
  378. else
  379. diag(n, "bad in raddr: <null>");
  380. p->reg = NREG;
  381. } else
  382. p->reg = a.reg;
  383. }
  384. void
  385. naddr(Node *n, Adr *a)
  386. {
  387. long v;
  388. a->type = D_NONE;
  389. if(n == Z)
  390. return;
  391. switch(n->op) {
  392. default:
  393. bad:
  394. diag(n, "bad in naddr: %O", n->op);
  395. break;
  396. case OREGISTER:
  397. a->type = D_REG;
  398. a->sym = S;
  399. a->reg = n->reg;
  400. if(a->reg >= NREG) {
  401. a->type = D_FREG;
  402. a->reg -= NREG;
  403. }
  404. break;
  405. case OIND:
  406. naddr(n->left, a);
  407. if(a->type == D_REG) {
  408. a->type = D_OREG;
  409. break;
  410. }
  411. if(a->type == D_CONST) {
  412. a->type = D_OREG;
  413. break;
  414. }
  415. goto bad;
  416. case OINDREG:
  417. a->type = D_OREG;
  418. a->sym = S;
  419. a->offset = n->xoffset;
  420. a->reg = n->reg;
  421. break;
  422. case ONAME:
  423. a->etype = n->etype;
  424. a->type = D_OREG;
  425. a->name = D_STATIC;
  426. a->sym = n->sym;
  427. a->offset = n->xoffset;
  428. if(n->class == CSTATIC)
  429. break;
  430. if(n->class == CEXTERN || n->class == CGLOBL) {
  431. a->name = D_EXTERN;
  432. break;
  433. }
  434. if(n->class == CAUTO) {
  435. a->name = D_AUTO;
  436. break;
  437. }
  438. if(n->class == CPARAM) {
  439. a->name = D_PARAM;
  440. break;
  441. }
  442. goto bad;
  443. case OCONST:
  444. a->sym = S;
  445. a->reg = NREG;
  446. if(typefd[n->type->etype]) {
  447. a->type = D_FCONST;
  448. a->dval = n->fconst;
  449. } else
  450. if(llconst(n)) {
  451. a->type = D_VCONST;
  452. a->vval = n->vconst;
  453. } else {
  454. a->type = D_CONST;
  455. a->offset = n->vconst;
  456. }
  457. break;
  458. case OADDR:
  459. naddr(n->left, a);
  460. if(a->type == D_OREG) {
  461. a->type = D_CONST;
  462. break;
  463. }
  464. goto bad;
  465. case OADD:
  466. if(n->left->op == OCONST) {
  467. naddr(n->left, a);
  468. v = a->offset;
  469. naddr(n->right, a);
  470. } else {
  471. naddr(n->right, a);
  472. v = a->offset;
  473. naddr(n->left, a);
  474. }
  475. a->offset += v;
  476. break;
  477. }
  478. }
  479. void
  480. fop(int as, int f1, int f2, Node *t)
  481. {
  482. Node nod1, nod2, nod3;
  483. nodreg(&nod1, t, NREG+f1);
  484. nodreg(&nod2, t, NREG+f2);
  485. regalloc(&nod3, t, t);
  486. gopcode(as, &nod1, &nod2, &nod3);
  487. gmove(&nod3, t);
  488. regfree(&nod3);
  489. }
  490. void
  491. gmove(Node *f, Node *t)
  492. {
  493. int ft, tt, a;
  494. Node nod;
  495. Prog *p1;
  496. double d;
  497. ft = f->type->etype;
  498. tt = t->type->etype;
  499. if(ft == TDOUBLE && f->op == OCONST) {
  500. d = f->fconst;
  501. if(d == 0.0) {
  502. a = FREGZERO;
  503. goto ffreg;
  504. }
  505. if(d == 0.5) {
  506. a = FREGHALF;
  507. goto ffreg;
  508. }
  509. if(d == 1.0) {
  510. a = FREGONE;
  511. goto ffreg;
  512. }
  513. if(d == 2.0) {
  514. a = FREGTWO;
  515. goto ffreg;
  516. }
  517. if(d == -.5) {
  518. fop(OSUB, FREGHALF, FREGZERO, t);
  519. return;
  520. }
  521. if(d == -1.0) {
  522. fop(OSUB, FREGONE, FREGZERO, t);
  523. return;
  524. }
  525. if(d == -2.0) {
  526. fop(OSUB, FREGTWO, FREGZERO, t);
  527. return;
  528. }
  529. if(d == 1.5) {
  530. fop(OADD, FREGONE, FREGHALF, t);
  531. return;
  532. }
  533. if(d == 2.5) {
  534. fop(OADD, FREGTWO, FREGHALF, t);
  535. return;
  536. }
  537. if(d == 3.0) {
  538. fop(OADD, FREGTWO, FREGONE, t);
  539. return;
  540. }
  541. }
  542. if(ft == TFLOAT && f->op == OCONST) {
  543. d = f->fconst;
  544. if(d == 0) {
  545. a = FREGZERO;
  546. ffreg:
  547. nodreg(&nod, f, NREG+a);
  548. gmove(&nod, t);
  549. return;
  550. }
  551. }
  552. /*
  553. * a load --
  554. * put it into a register then
  555. * worry what to do with it.
  556. */
  557. if(f->op == ONAME || f->op == OINDREG || f->op == OIND) {
  558. switch(ft) {
  559. default:
  560. if(typefd[tt]) {
  561. /* special case can load mem to Freg */
  562. regalloc(&nod, t, t);
  563. gins(AMOVW, f, &nod);
  564. a = AMOVWD;
  565. if(tt == TFLOAT)
  566. a = AMOVWF;
  567. gins(a, &nod, &nod);
  568. gmove(&nod, t);
  569. regfree(&nod);
  570. return;
  571. }
  572. a = AMOVW;
  573. break;
  574. case TCHAR:
  575. a = AMOVB;
  576. break;
  577. case TUCHAR:
  578. a = AMOVBU;
  579. break;
  580. case TSHORT:
  581. a = AMOVH;
  582. break;
  583. case TUSHORT:
  584. a = AMOVHU;
  585. break;
  586. case TFLOAT:
  587. a = AMOVF;
  588. break;
  589. case TDOUBLE:
  590. a = AMOVD;
  591. break;
  592. case TUVLONG:
  593. case TVLONG:
  594. a = AMOVV;
  595. break;
  596. }
  597. if(typechlp[ft] && typeilp[tt])
  598. regalloc(&nod, t, t);
  599. else
  600. regalloc(&nod, f, t);
  601. gins(a, f, &nod);
  602. gmove(&nod, t);
  603. regfree(&nod);
  604. return;
  605. }
  606. /*
  607. * a store --
  608. * put it into a register then
  609. * store it.
  610. */
  611. if(t->op == ONAME || t->op == OINDREG || t->op == OIND) {
  612. switch(tt) {
  613. default:
  614. a = AMOVW;
  615. break;
  616. case TUCHAR:
  617. a = AMOVBU;
  618. break;
  619. case TCHAR:
  620. a = AMOVB;
  621. break;
  622. case TUSHORT:
  623. a = AMOVHU;
  624. break;
  625. case TSHORT:
  626. a = AMOVH;
  627. break;
  628. case TFLOAT:
  629. a = AMOVF;
  630. break;
  631. case TDOUBLE:
  632. a = AMOVD;
  633. break;
  634. case TUVLONG:
  635. case TVLONG:
  636. a = AMOVV;
  637. break;
  638. }
  639. if(!typefd[ft] && vconst(f) == 0) {
  640. gins(a, f, t);
  641. return;
  642. }
  643. if(ft == tt)
  644. regalloc(&nod, t, f);
  645. else
  646. regalloc(&nod, t, Z);
  647. gmove(f, &nod);
  648. gins(a, &nod, t);
  649. regfree(&nod);
  650. return;
  651. }
  652. /*
  653. * type x type cross table
  654. */
  655. a = AGOK;
  656. switch(ft) {
  657. case TUVLONG:
  658. case TVLONG:
  659. switch(tt) {
  660. case TUVLONG:
  661. case TVLONG:
  662. a = AMOVV;
  663. break;
  664. case TINT:
  665. case TUINT:
  666. case TLONG:
  667. case TULONG:
  668. case TIND:
  669. case TSHORT:
  670. case TUSHORT:
  671. case TCHAR:
  672. case TUCHAR:
  673. a = AMOVW;
  674. break;
  675. case TDOUBLE:
  676. gins(AMOVW, f, t);
  677. gins(AMOVWD, t, t);
  678. if(ft == TULONG || ft == TUINT) {
  679. regalloc(&nod, t, Z);
  680. gins(ACMPGED, t, Z);
  681. p->reg = FREGZERO;
  682. gins(ABFPT, Z, Z);
  683. p1 = p;
  684. gins(AMOVD, nodfconst(4294967296.), &nod);
  685. gins(AADDD, &nod, t);
  686. patch(p1, pc);
  687. regfree(&nod);
  688. }
  689. return;
  690. case TFLOAT:
  691. gins(AMOVW, f, t);
  692. gins(AMOVWF, t, t);
  693. if(ft == TULONG || ft == TUINT) {
  694. regalloc(&nod, t, Z);
  695. gins(ACMPGEF, t, Z);
  696. p->reg = FREGZERO;
  697. gins(ABFPT, Z, Z);
  698. p1 = p;
  699. gins(AMOVF, nodfconst(4294967296.), &nod);
  700. gins(AADDF, &nod, t);
  701. patch(p1, pc);
  702. regfree(&nod);
  703. }
  704. return;
  705. }
  706. break;
  707. case TDOUBLE:
  708. case TFLOAT:
  709. switch(tt) {
  710. case TDOUBLE:
  711. a = AMOVD;
  712. if(ft == TFLOAT)
  713. a = AMOVFD;
  714. break;
  715. case TFLOAT:
  716. a = AMOVDF;
  717. if(ft == TFLOAT)
  718. a = AMOVF;
  719. break;
  720. case TINT:
  721. case TUINT:
  722. case TLONG:
  723. case TULONG:
  724. case TIND:
  725. case TSHORT:
  726. case TUSHORT:
  727. case TCHAR:
  728. case TUCHAR:
  729. regalloc(&nod, f, Z);
  730. gins(ATRUNCDW, f, &nod);
  731. if(ft == TFLOAT)
  732. p->as = ATRUNCFW;
  733. gins(AMOVW, &nod, t);
  734. regfree(&nod);
  735. return;
  736. case TUVLONG:
  737. case TVLONG:
  738. regalloc(&nod, f, Z);
  739. gins(ATRUNCDV, f, &nod);
  740. if(ft == TFLOAT)
  741. p->as = ATRUNCFV;
  742. gins(AMOVV, &nod, t);
  743. regfree(&nod);
  744. return;
  745. }
  746. break;
  747. case TINT:
  748. case TUINT:
  749. case TLONG:
  750. case TULONG:
  751. case TIND:
  752. switch(tt) {
  753. case TDOUBLE:
  754. gins(AMOVW, f, t);
  755. gins(AMOVWD, t, t);
  756. if(ft == TULONG || ft == TUINT) {
  757. regalloc(&nod, t, Z);
  758. gins(ACMPGED, t, Z);
  759. p->reg = FREGZERO;
  760. gins(ABFPT, Z, Z);
  761. p1 = p;
  762. gins(AMOVD, nodfconst(4294967296.), &nod);
  763. gins(AADDD, &nod, t);
  764. patch(p1, pc);
  765. regfree(&nod);
  766. }
  767. return;
  768. case TFLOAT:
  769. gins(AMOVW, f, t);
  770. gins(AMOVWF, t, t);
  771. if(ft == TULONG || ft == TUINT) {
  772. regalloc(&nod, t, Z);
  773. gins(ACMPGEF, t, Z);
  774. p->reg = FREGZERO;
  775. gins(ABFPT, Z, Z);
  776. p1 = p;
  777. gins(AMOVF, nodfconst(4294967296.), &nod);
  778. gins(AADDF, &nod, t);
  779. patch(p1, pc);
  780. regfree(&nod);
  781. }
  782. return;
  783. case TUVLONG:
  784. case TVLONG:
  785. if(ft == TULONG || ft == TUINT) {
  786. a = AMOVWU;
  787. break;
  788. }
  789. case TINT:
  790. case TUINT:
  791. case TLONG:
  792. case TULONG:
  793. case TIND:
  794. case TSHORT:
  795. case TUSHORT:
  796. case TCHAR:
  797. case TUCHAR:
  798. a = AMOVW;
  799. break;
  800. }
  801. break;
  802. case TSHORT:
  803. switch(tt) {
  804. case TDOUBLE:
  805. regalloc(&nod, f, Z);
  806. gins(AMOVH, f, &nod);
  807. gins(AMOVW, &nod, t);
  808. gins(AMOVWD, t, t);
  809. regfree(&nod);
  810. return;
  811. case TFLOAT:
  812. regalloc(&nod, f, Z);
  813. gins(AMOVH, f, &nod);
  814. gins(AMOVW, &nod, t);
  815. gins(AMOVWF, t, t);
  816. regfree(&nod);
  817. return;
  818. case TINT:
  819. case TUINT:
  820. case TLONG:
  821. case TULONG:
  822. case TVLONG:
  823. case TUVLONG:
  824. case TIND:
  825. a = AMOVH;
  826. break;
  827. case TSHORT:
  828. case TUSHORT:
  829. case TCHAR:
  830. case TUCHAR:
  831. a = AMOVW;
  832. break;
  833. }
  834. break;
  835. case TUSHORT:
  836. switch(tt) {
  837. case TDOUBLE:
  838. regalloc(&nod, f, Z);
  839. gins(AMOVHU, f, &nod);
  840. gins(AMOVW, &nod, t);
  841. gins(AMOVWD, t, t);
  842. regfree(&nod);
  843. return;
  844. case TFLOAT:
  845. regalloc(&nod, f, Z);
  846. gins(AMOVHU, f, &nod);
  847. gins(AMOVW, &nod, t);
  848. gins(AMOVWF, t, t);
  849. regfree(&nod);
  850. return;
  851. case TINT:
  852. case TUINT:
  853. case TLONG:
  854. case TULONG:
  855. case TVLONG:
  856. case TUVLONG:
  857. case TIND:
  858. a = AMOVHU;
  859. break;
  860. case TSHORT:
  861. case TUSHORT:
  862. case TCHAR:
  863. case TUCHAR:
  864. a = AMOVW;
  865. break;
  866. }
  867. break;
  868. case TCHAR:
  869. switch(tt) {
  870. case TDOUBLE:
  871. regalloc(&nod, f, Z);
  872. gins(AMOVB, f, &nod);
  873. gins(AMOVW, &nod, t);
  874. gins(AMOVWD, t, t);
  875. regfree(&nod);
  876. return;
  877. case TFLOAT:
  878. regalloc(&nod, f, Z);
  879. gins(AMOVB, f, &nod);
  880. gins(AMOVW, &nod, t);
  881. gins(AMOVWF, t, t);
  882. regfree(&nod);
  883. return;
  884. case TINT:
  885. case TUINT:
  886. case TLONG:
  887. case TULONG:
  888. case TVLONG:
  889. case TUVLONG:
  890. case TIND:
  891. case TSHORT:
  892. case TUSHORT:
  893. a = AMOVB;
  894. break;
  895. case TCHAR:
  896. case TUCHAR:
  897. a = AMOVW;
  898. break;
  899. }
  900. break;
  901. case TUCHAR:
  902. switch(tt) {
  903. case TDOUBLE:
  904. regalloc(&nod, f, Z);
  905. gins(AMOVBU, f, &nod);
  906. gins(AMOVW, &nod, t);
  907. gins(AMOVWD, t, t);
  908. regfree(&nod);
  909. return;
  910. case TFLOAT:
  911. regalloc(&nod, f, Z);
  912. gins(AMOVBU, f, &nod);
  913. gins(AMOVW, &nod, t);
  914. gins(AMOVWF, t, t);
  915. regfree(&nod);
  916. return;
  917. case TINT:
  918. case TUINT:
  919. case TLONG:
  920. case TULONG:
  921. case TVLONG:
  922. case TUVLONG:
  923. case TIND:
  924. case TSHORT:
  925. case TUSHORT:
  926. a = AMOVBU;
  927. break;
  928. case TCHAR:
  929. case TUCHAR:
  930. a = AMOVW;
  931. break;
  932. }
  933. break;
  934. }
  935. if(a == AGOK)
  936. diag(Z, "bad opcode in gmove %T -> %T", f->type, t->type);
  937. if(a == AMOVW || a == AMOVF || a == AMOVD || a == AMOVV)
  938. if(samaddr(f, t))
  939. return;
  940. gins(a, f, t);
  941. }
  942. void
  943. gins(int a, Node *f, Node *t)
  944. {
  945. nextpc();
  946. p->as = a;
  947. if(f != Z)
  948. naddr(f, &p->from);
  949. if(t != Z)
  950. naddr(t, &p->to);
  951. if(debug['g'])
  952. print("%P\n", p);
  953. }
  954. void
  955. gopcode(int o, Node *f1, Node *f2, Node *t)
  956. {
  957. int a, et, ett;
  958. Adr ta;
  959. Node nod;
  960. et = TLONG;
  961. if(f1 != Z && f1->type != T)
  962. et = f1->type->etype;
  963. ett = TLONG;
  964. if(t != Z && t->type != T)
  965. ett = t->type->etype;
  966. if(llconst(f1) && o != OAS) {
  967. regalloc(&nod, f1, Z);
  968. gmove(f1, &nod);
  969. gopcode(o, &nod, f2, t);
  970. regfree(&nod);
  971. return;
  972. }
  973. a = AGOK;
  974. switch(o) {
  975. case OAS:
  976. gmove(f1, t);
  977. return;
  978. case OASADD:
  979. case OADD:
  980. a = AADDU;
  981. if(et == TVLONG || et == TUVLONG)
  982. a = AADDVU;
  983. else
  984. if(et == TFLOAT)
  985. a = AADDF;
  986. else
  987. if(et == TDOUBLE)
  988. a = AADDD;
  989. break;
  990. case OASSUB:
  991. case OSUB:
  992. a = ASUBU;
  993. if(et == TVLONG || et == TUVLONG)
  994. a = ASUBVU;
  995. else
  996. if(et == TFLOAT)
  997. a = ASUBF;
  998. else
  999. if(et == TDOUBLE)
  1000. a = ASUBD;
  1001. break;
  1002. case OASOR:
  1003. case OOR:
  1004. a = AOR;
  1005. break;
  1006. case OASAND:
  1007. case OAND:
  1008. a = AAND;
  1009. break;
  1010. case OASXOR:
  1011. case OXOR:
  1012. a = AXOR;
  1013. break;
  1014. case OASLSHR:
  1015. case OLSHR:
  1016. a = ASRL;
  1017. if(ett == TVLONG || ett == TUVLONG)
  1018. a = ASRLV;
  1019. break;
  1020. case OASASHR:
  1021. case OASHR:
  1022. a = ASRA;
  1023. if(ett == TVLONG || ett == TUVLONG)
  1024. a = ASRAV;
  1025. break;
  1026. case OASASHL:
  1027. case OASHL:
  1028. a = ASLL;
  1029. if(ett == TVLONG || ett == TUVLONG)
  1030. a = ASLLV;
  1031. break;
  1032. case OFUNC:
  1033. a = AJAL;
  1034. break;
  1035. case OCOND:
  1036. a = ASGTU;
  1037. break;
  1038. case OCOMMA:
  1039. a = ASGT;
  1040. break;
  1041. case OASMUL:
  1042. case OMUL:
  1043. if(et == TFLOAT) {
  1044. a = AMULF;
  1045. break;
  1046. } else
  1047. if(et == TDOUBLE) {
  1048. a = AMULD;
  1049. break;
  1050. }
  1051. a = AMUL;
  1052. if(et == TVLONG || et == TUVLONG)
  1053. a = AMULV;
  1054. goto muldiv;
  1055. case OASDIV:
  1056. case ODIV:
  1057. if(et == TFLOAT) {
  1058. a = ADIVF;
  1059. break;
  1060. } else
  1061. if(et == TDOUBLE) {
  1062. a = ADIVD;
  1063. break;
  1064. }
  1065. a = ADIV;
  1066. if(et == TVLONG || et == TUVLONG)
  1067. a = ADIVV;
  1068. goto muldiv;
  1069. case OASMOD:
  1070. case OMOD:
  1071. a = ADIV;
  1072. o = OMOD;
  1073. if(et == TVLONG || et == TUVLONG)
  1074. a = ADIVV;
  1075. goto muldiv;
  1076. case OASLMUL:
  1077. case OLMUL:
  1078. a = AMULU;
  1079. if(et == TVLONG || et == TUVLONG)
  1080. a = AMULVU;
  1081. goto muldiv;
  1082. case OASLMOD:
  1083. case OLMOD:
  1084. o = OMOD;
  1085. case OASLDIV:
  1086. case OLDIV:
  1087. a = ADIVU;
  1088. if(et == TVLONG || et == TUVLONG)
  1089. a = ADIVVU;
  1090. goto muldiv;
  1091. muldiv:
  1092. nextpc();
  1093. naddr(f1, &p->from);
  1094. if(f2 == Z)
  1095. raddr(t, p);
  1096. else
  1097. raddr(f2, p);
  1098. p->as = a;
  1099. if(debug['g'])
  1100. print("%P\n", p);
  1101. nextpc();
  1102. p->as = AMOVW;
  1103. if(et == TVLONG || et == TUVLONG)
  1104. p->as = AMOVV;
  1105. a = D_LO;
  1106. if(o == OMOD)
  1107. a = D_HI;
  1108. p->from.type = a;
  1109. naddr(t, &p->to);
  1110. if(debug['g'])
  1111. print("%P\n", p);
  1112. return;
  1113. case OEQ:
  1114. if(!typefd[et]) {
  1115. a = ABEQ;
  1116. break;
  1117. }
  1118. case ONE:
  1119. if(!typefd[et]) {
  1120. a = ABNE;
  1121. break;
  1122. }
  1123. case OLT:
  1124. case OLE:
  1125. case OGE:
  1126. case OGT:
  1127. if(typefd[et]) {
  1128. nextpc();
  1129. if(et == TFLOAT) {
  1130. a = ACMPGTF;
  1131. if(o == OEQ || o == ONE)
  1132. a = ACMPEQF;
  1133. else
  1134. if(o == OLT || o == OGE)
  1135. a = ACMPGEF;
  1136. } else {
  1137. a = ACMPGTD;
  1138. if(o == OEQ || o == ONE)
  1139. a = ACMPEQD;
  1140. else
  1141. if(o == OLT || o == OGE)
  1142. a = ACMPGED;
  1143. }
  1144. p->as = a;
  1145. naddr(f1, &p->from);
  1146. raddr(f2, p);
  1147. if(debug['g'])
  1148. print("%P\n", p);
  1149. nextpc();
  1150. a = ABFPF;
  1151. if(o == OEQ || o == OGE || o == OGT)
  1152. a = ABFPT;
  1153. p->as = a;
  1154. if(debug['g'])
  1155. print("%P\n", p);
  1156. return;
  1157. }
  1158. if(vconst(f1) == 0 || vconst(f2) == 0) {
  1159. if(vconst(f1) == 0) {
  1160. o = invrel[relindex(o)];
  1161. f1 = f2;
  1162. }
  1163. switch(o) {
  1164. case OLT:
  1165. a = ABLTZ;
  1166. break;
  1167. case OLE:
  1168. a = ABLEZ;
  1169. break;
  1170. case OGE:
  1171. a = ABGEZ;
  1172. break;
  1173. case OGT:
  1174. a = ABGTZ;
  1175. break;
  1176. }
  1177. f2 = Z;
  1178. break;
  1179. }
  1180. case OLO:
  1181. case OLS:
  1182. case OHS:
  1183. case OHI:
  1184. nextpc();
  1185. if(o == OLE || o == OGT || o == OLS || o == OHI) {
  1186. naddr(f1, &p->from);
  1187. raddr(f2, p);
  1188. } else {
  1189. naddr(f2, &p->from);
  1190. raddr(f1, p);
  1191. }
  1192. naddr(&regnode, &p->to);
  1193. p->to.reg = tmpreg();
  1194. a = ASGT;
  1195. if(o == OLO || o == OLS || o == OHS || o == OHI)
  1196. a = ASGTU;
  1197. p->as = a;
  1198. if(debug['g'])
  1199. print("%P\n", p);
  1200. nextpc();
  1201. naddr(&regnode, &p->from);
  1202. p->from.reg = tmpreg();
  1203. a = ABEQ;
  1204. if(o == OLT || o == OGT || o == OLO || o == OHI)
  1205. a = ABNE;
  1206. p->as = a;
  1207. if(debug['g'])
  1208. print("%P\n", p);
  1209. return;
  1210. }
  1211. if(a == AGOK)
  1212. diag(Z, "bad in gopcode %O", o);
  1213. nextpc();
  1214. p->as = a;
  1215. if(f1 != Z)
  1216. naddr(f1, &p->from);
  1217. if(f2 != Z) {
  1218. naddr(f2, &ta);
  1219. p->reg = ta.reg;
  1220. if(ta.type == D_CONST && ta.offset == 0)
  1221. p->reg = REGZERO;
  1222. }
  1223. if(t != Z)
  1224. naddr(t, &p->to);
  1225. if(debug['g'])
  1226. print("%P\n", p);
  1227. }
  1228. int
  1229. samaddr(Node *f, Node *t)
  1230. {
  1231. if(f->op != t->op)
  1232. return 0;
  1233. switch(f->op) {
  1234. case OREGISTER:
  1235. if(f->reg != t->reg)
  1236. break;
  1237. return 1;
  1238. }
  1239. return 0;
  1240. }
  1241. void
  1242. gbranch(int o)
  1243. {
  1244. int a;
  1245. a = AGOK;
  1246. switch(o) {
  1247. case ORETURN:
  1248. a = ARET;
  1249. break;
  1250. case OGOTO:
  1251. a = AJMP;
  1252. break;
  1253. }
  1254. nextpc();
  1255. if(a == AGOK) {
  1256. diag(Z, "bad in gbranch %O", o);
  1257. nextpc();
  1258. }
  1259. p->as = a;
  1260. }
  1261. void
  1262. patch(Prog *op, long pc)
  1263. {
  1264. op->to.offset = pc;
  1265. op->to.type = D_BRANCH;
  1266. }
  1267. void
  1268. gpseudo(int a, Sym *s, Node *n)
  1269. {
  1270. nextpc();
  1271. p->as = a;
  1272. p->from.type = D_OREG;
  1273. p->from.sym = s;
  1274. p->from.name = D_EXTERN;
  1275. if(s->class == CSTATIC)
  1276. p->from.name = D_STATIC;
  1277. naddr(n, &p->to);
  1278. if(a == ADATA || a == AGLOBL)
  1279. pc--;
  1280. }
  1281. int
  1282. sconst(Node *n)
  1283. {
  1284. vlong vv;
  1285. if(n->op == OCONST) {
  1286. if(!typefd[n->type->etype]) {
  1287. vv = n->vconst;
  1288. if(vv >= (vlong)-32766 && vv < (vlong)32766)
  1289. return 1;
  1290. }
  1291. }
  1292. return 0;
  1293. }
  1294. int
  1295. llconst(Node *n)
  1296. {
  1297. vlong vv;
  1298. if(n != Z && n->op == OCONST) {
  1299. if(typev[n->type->etype]) {
  1300. vv = n->vconst >> 32;
  1301. if(vv != 0 && vv != -1)
  1302. return 1;
  1303. }
  1304. }
  1305. return 0;
  1306. }
  1307. int
  1308. sval(long v)
  1309. {
  1310. if(v >= -32766L && v < 32766L)
  1311. return 1;
  1312. return 0;
  1313. }
  1314. long
  1315. exreg(Type *t)
  1316. {
  1317. long o;
  1318. if(typechlp[t->etype]) {
  1319. if(exregoffset <= 16)
  1320. return 0;
  1321. o = exregoffset;
  1322. exregoffset--;
  1323. return o;
  1324. }
  1325. if(typefd[t->etype]) {
  1326. if(exfregoffset <= 16)
  1327. return 0;
  1328. o = exfregoffset + NREG;
  1329. exfregoffset--;
  1330. return o;
  1331. }
  1332. return 0;
  1333. }
  1334. schar ewidth[NTYPE] =
  1335. {
  1336. -1, /*[TXXX]*/
  1337. SZ_CHAR, /*[TCHAR]*/
  1338. SZ_CHAR, /*[TUCHAR]*/
  1339. SZ_SHORT, /*[TSHORT]*/
  1340. SZ_SHORT, /*[TUSHORT]*/
  1341. SZ_INT, /*[TINT]*/
  1342. SZ_INT, /*[TUINT]*/
  1343. SZ_LONG, /*[TLONG]*/
  1344. SZ_LONG, /*[TULONG]*/
  1345. SZ_VLONG, /*[TVLONG]*/
  1346. SZ_VLONG, /*[TUVLONG]*/
  1347. SZ_FLOAT, /*[TFLOAT]*/
  1348. SZ_DOUBLE, /*[TDOUBLE]*/
  1349. SZ_IND, /*[TIND]*/
  1350. 0, /*[TFUNC]*/
  1351. -1, /*[TARRAY]*/
  1352. 0, /*[TVOID]*/
  1353. -1, /*[TSTRUCT]*/
  1354. -1, /*[TUNION]*/
  1355. SZ_INT, /*[TENUM]*/
  1356. };
  1357. long ncast[NTYPE] =
  1358. {
  1359. 0, /*[TXXX]*/
  1360. BCHAR|BUCHAR, /*[TCHAR]*/
  1361. BCHAR|BUCHAR, /*[TUCHAR]*/
  1362. BSHORT|BUSHORT, /*[TSHORT]*/
  1363. BSHORT|BUSHORT, /*[TUSHORT]*/
  1364. BINT|BUINT|BLONG|BULONG|BIND, /*[TINT]*/
  1365. BINT|BUINT|BLONG|BULONG|BIND, /*[TUINT]*/
  1366. BINT|BUINT|BLONG|BULONG|BIND, /*[TLONG]*/
  1367. BINT|BUINT|BLONG|BULONG|BIND, /*[TULONG]*/
  1368. BVLONG|BUVLONG, /*[TVLONG]*/
  1369. BVLONG|BUVLONG, /*[TUVLONG]*/
  1370. BFLOAT, /*[TFLOAT]*/
  1371. BDOUBLE, /*[TDOUBLE]*/
  1372. BLONG|BULONG|BIND, /*[TIND]*/
  1373. 0, /*[TFUNC]*/
  1374. 0, /*[TARRAY]*/
  1375. 0, /*[TVOID]*/
  1376. BSTRUCT, /*[TSTRUCT]*/
  1377. BUNION, /*[TUNION]*/
  1378. 0, /*[TENUM]*/
  1379. };