PageRenderTime 83ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/utils/tc/txt.c

https://bitbucket.org/floren/inferno/
C | 1199 lines | 1064 code | 100 blank | 35 comment | 219 complexity | 385bffeb36c7839d17e7413899969ba8 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. Type *t;
  6. thechar = 't';
  7. thestring = "arm";
  8. exregoffset = REGEXT;
  9. exfregoffset = FREGEXT;
  10. listinit();
  11. nstring = 0;
  12. mnstring = 0;
  13. nrathole = 0;
  14. pc = 0;
  15. breakpc = -1;
  16. continpc = -1;
  17. cases = C;
  18. firstp = P;
  19. lastp = P;
  20. tfield = types[TLONG];
  21. zprog.link = P;
  22. zprog.as = AGOK;
  23. zprog.reg = NREG;
  24. zprog.from.type = D_NONE;
  25. zprog.from.name = D_NONE;
  26. zprog.from.reg = NREG;
  27. zprog.to = zprog.from;
  28. regnode.op = OREGISTER;
  29. regnode.class = CEXREG;
  30. regnode.reg = REGTMPT;
  31. regnode.complex = 0;
  32. regnode.addable = 11;
  33. regnode.type = types[TLONG];
  34. constnode.op = OCONST;
  35. constnode.class = CXXX;
  36. constnode.complex = 0;
  37. constnode.addable = 20;
  38. constnode.type = types[TLONG];
  39. fconstnode.op = OCONST;
  40. fconstnode.class = CXXX;
  41. fconstnode.complex = 0;
  42. fconstnode.addable = 20;
  43. fconstnode.type = types[TDOUBLE];
  44. nodsafe = new(ONAME, Z, Z);
  45. nodsafe->sym = slookup(".safe");
  46. nodsafe->type = types[TINT];
  47. nodsafe->etype = types[TINT]->etype;
  48. nodsafe->class = CAUTO;
  49. complex(nodsafe);
  50. t = typ(TARRAY, types[TCHAR]);
  51. symrathole = slookup(".rathole");
  52. symrathole->class = CGLOBL;
  53. symrathole->type = t;
  54. nodrat = new(ONAME, Z, Z);
  55. nodrat->sym = symrathole;
  56. nodrat->type = types[TIND];
  57. nodrat->etype = TVOID;
  58. nodrat->class = CGLOBL;
  59. complex(nodrat);
  60. nodrat->type = t;
  61. nodret = new(ONAME, Z, Z);
  62. nodret->sym = slookup(".ret");
  63. nodret->type = types[TIND];
  64. nodret->etype = TIND;
  65. nodret->class = CPARAM;
  66. nodret = new(OIND, nodret, Z);
  67. complex(nodret);
  68. com64init();
  69. memset(reg, 0, sizeof(reg));
  70. // reg[REGTMPT] = 1;
  71. }
  72. void
  73. gclean(void)
  74. {
  75. int i;
  76. Sym *s;
  77. for(i=0; i<NREG; i++)
  78. if(reg[i])
  79. diag(Z, "reg %d left allocated", i);
  80. for(i=NREG; i<NREG+NFREG; i++)
  81. if(reg[i])
  82. diag(Z, "freg %d left allocated", i-NREG);
  83. while(mnstring)
  84. outstring("", 1L);
  85. symstring->type->width = nstring;
  86. symrathole->type->width = nrathole;
  87. for(i=0; i<NHASH; i++)
  88. for(s = hash[i]; s != S; s = s->link) {
  89. if(s->type == T)
  90. continue;
  91. if(s->type->width == 0)
  92. continue;
  93. if(s->class != CGLOBL && s->class != CSTATIC)
  94. continue;
  95. if(s->type == types[TENUM])
  96. continue;
  97. gpseudo(AGLOBL, s, nodconst(s->type->width));
  98. }
  99. nextpc();
  100. p->as = AEND;
  101. outcode();
  102. }
  103. void
  104. nextpc(void)
  105. {
  106. p = alloc(sizeof(*p));
  107. *p = zprog;
  108. p->lineno = nearln;
  109. pc++;
  110. if(firstp == P) {
  111. firstp = p;
  112. lastp = p;
  113. return;
  114. }
  115. lastp->link = p;
  116. lastp = p;
  117. }
  118. void
  119. gargs(Node *n, Node *tn1, Node *tn2)
  120. {
  121. long regs;
  122. Node fnxargs[20], *fnxp;
  123. regs = cursafe;
  124. fnxp = fnxargs;
  125. garg1(n, tn1, tn2, 0, &fnxp); /* compile fns to temps */
  126. curarg = 0;
  127. fnxp = fnxargs;
  128. garg1(n, tn1, tn2, 1, &fnxp); /* compile normal args and temps */
  129. cursafe = regs;
  130. }
  131. void
  132. garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
  133. {
  134. Node nod;
  135. if(n == Z)
  136. return;
  137. if(n->op == OLIST) {
  138. garg1(n->left, tn1, tn2, f, fnxp);
  139. garg1(n->right, tn1, tn2, f, fnxp);
  140. return;
  141. }
  142. if(f == 0) {
  143. if(n->complex >= FNX) {
  144. regsalloc(*fnxp, n);
  145. nod = znode;
  146. nod.op = OAS;
  147. nod.left = *fnxp;
  148. nod.right = n;
  149. nod.type = n->type;
  150. cgen(&nod, Z);
  151. (*fnxp)++;
  152. }
  153. return;
  154. }
  155. if(typesuv[n->type->etype]) {
  156. regaalloc(tn2, n);
  157. if(n->complex >= FNX) {
  158. sugen(*fnxp, tn2, n->type->width);
  159. (*fnxp)++;
  160. } else
  161. sugen(n, tn2, n->type->width);
  162. return;
  163. }
  164. if(REGARG >= 0 && curarg == 0 && typechlp[n->type->etype]) {
  165. regaalloc1(tn1, n);
  166. if(n->complex >= FNX) {
  167. cgen(*fnxp, tn1);
  168. (*fnxp)++;
  169. } else
  170. cgen(n, tn1);
  171. return;
  172. }
  173. regalloc(tn1, n, Z);
  174. if(n->complex >= FNX) {
  175. cgen(*fnxp, tn1);
  176. (*fnxp)++;
  177. } else
  178. cgen(n, tn1);
  179. regaalloc(tn2, n);
  180. gopcode(OAS, tn1, Z, tn2);
  181. regfree(tn1);
  182. }
  183. Node*
  184. nodconst(long v)
  185. {
  186. constnode.vconst = v;
  187. return &constnode;
  188. }
  189. Node*
  190. nod32const(vlong v)
  191. {
  192. constnode.vconst = v & MASK(32);
  193. return &constnode;
  194. }
  195. Node*
  196. nodfconst(double d)
  197. {
  198. fconstnode.fconst = d;
  199. return &fconstnode;
  200. }
  201. void
  202. nodreg(Node *n, Node *nn, int reg)
  203. {
  204. *n = regnode;
  205. n->reg = reg;
  206. n->type = nn->type;
  207. n->lineno = nn->lineno;
  208. }
  209. void
  210. regret(Node *n, Node *nn)
  211. {
  212. int r;
  213. r = REGRET;
  214. if(typefd[nn->type->etype])
  215. r = FREGRET+NREG;
  216. nodreg(n, nn, r);
  217. reg[r]++;
  218. }
  219. int
  220. tmpreg(void)
  221. {
  222. int i;
  223. for(i=REGRET+1; i<NREG; i++)
  224. if(reg[i] == 0)
  225. return i;
  226. diag(Z, "out of fixed tmp registers");
  227. return 0;
  228. }
  229. void
  230. regalloc(Node *n, Node *tn, Node *o)
  231. {
  232. int i, j;
  233. static int lasti;
  234. switch(tn->type->etype) {
  235. case TCHAR:
  236. case TUCHAR:
  237. case TSHORT:
  238. case TUSHORT:
  239. case TINT:
  240. case TUINT:
  241. case TLONG:
  242. case TULONG:
  243. case TIND:
  244. if(o != Z && o->op == OREGISTER) {
  245. i = o->reg;
  246. if(i >= 0 && i < NREG)
  247. goto out;
  248. }
  249. j = lasti + REGRET+1;
  250. for(i=REGRET+1; i<REGTMPT; i++) {
  251. if(j >= REGTMPT)
  252. j = REGRET+1;
  253. if(reg[j] == 0) {
  254. i = j;
  255. goto out;
  256. }
  257. j++;
  258. }
  259. diag(tn, "out of fixed registers");
  260. goto err;
  261. case TFLOAT:
  262. case TDOUBLE:
  263. case TVLONG:
  264. if(o != Z && o->op == OREGISTER) {
  265. i = o->reg;
  266. if(i >= NREG && i < NREG+NFREG)
  267. goto out;
  268. }
  269. j = 0*2 + NREG;
  270. for(i=NREG; i<NREG+NFREG; i++) {
  271. if(j >= NREG+NFREG)
  272. j = NREG;
  273. if(reg[j] == 0) {
  274. i = j;
  275. goto out;
  276. }
  277. j++;
  278. }
  279. diag(tn, "out of float registers");
  280. goto err;
  281. }
  282. diag(tn, "unknown type in regalloc: %T", tn->type);
  283. err:
  284. nodreg(n, tn, 0);
  285. return;
  286. out:
  287. reg[i]++;
  288. /* lasti++; *** StrongARM does register forwarding */
  289. /*
  290. if(lasti >= 5)
  291. lasti = 0;
  292. */
  293. nodreg(n, tn, i);
  294. }
  295. void
  296. regialloc(Node *n, Node *tn, Node *o)
  297. {
  298. Node nod;
  299. nod = *tn;
  300. nod.type = types[TIND];
  301. regalloc(n, &nod, o);
  302. }
  303. void
  304. regfree(Node *n)
  305. {
  306. int i;
  307. i = 0;
  308. if(n->op != OREGISTER && n->op != OINDREG)
  309. goto err;
  310. i = n->reg;
  311. if(i < 0 || i >= sizeof(reg))
  312. goto err;
  313. if(reg[i] <= 0)
  314. goto err;
  315. reg[i]--;
  316. return;
  317. err:
  318. diag(n, "error in regfree: %d", i);
  319. }
  320. void
  321. regsalloc(Node *n, Node *nn)
  322. {
  323. cursafe = align(cursafe, nn->type, Aaut3);
  324. maxargsafe = maxround(maxargsafe, cursafe+curarg);
  325. *n = *nodsafe;
  326. n->xoffset = -(stkoff + cursafe);
  327. n->type = nn->type;
  328. n->etype = nn->type->etype;
  329. n->lineno = nn->lineno;
  330. }
  331. void
  332. regaalloc1(Node *n, Node *nn)
  333. {
  334. nodreg(n, nn, REGARG);
  335. reg[REGARG]++;
  336. curarg = align(curarg, nn->type, Aarg1);
  337. curarg = align(curarg, nn->type, Aarg2);
  338. maxargsafe = maxround(maxargsafe, cursafe+curarg);
  339. }
  340. void
  341. regaalloc(Node *n, Node *nn)
  342. {
  343. curarg = align(curarg, nn->type, Aarg1);
  344. *n = *nn;
  345. n->op = OINDREG;
  346. n->reg = REGSP;
  347. n->xoffset = curarg + SZ_LONG;
  348. n->complex = 0;
  349. n->addable = 20;
  350. curarg = align(curarg, nn->type, Aarg2);
  351. maxargsafe = maxround(maxargsafe, cursafe+curarg);
  352. }
  353. void
  354. regind(Node *n, Node *nn)
  355. {
  356. if(n->op != OREGISTER) {
  357. diag(n, "regind not OREGISTER");
  358. return;
  359. }
  360. n->op = OINDREG;
  361. n->type = nn->type;
  362. }
  363. void
  364. raddr(Node *n, Prog *p)
  365. {
  366. Adr a;
  367. naddr(n, &a);
  368. if(R0ISZERO && a.type == D_CONST && a.offset == 0) {
  369. a.type = D_REG;
  370. a.reg = 0;
  371. }
  372. if(a.type != D_REG && a.type != D_FREG) {
  373. if(n)
  374. diag(n, "bad in raddr: %O", n->op);
  375. else
  376. diag(n, "bad in raddr: <null>");
  377. p->reg = NREG;
  378. } else
  379. p->reg = a.reg;
  380. }
  381. void
  382. naddr(Node *n, Adr *a)
  383. {
  384. long v;
  385. a->type = D_NONE;
  386. if(n == Z)
  387. return;
  388. switch(n->op) {
  389. default:
  390. bad:
  391. diag(n, "bad in naddr: %O", n->op);
  392. break;
  393. case OREGISTER:
  394. a->type = D_REG;
  395. a->sym = S;
  396. a->reg = n->reg;
  397. if(a->reg >= NREG) {
  398. a->type = D_FREG;
  399. a->reg -= NREG;
  400. }
  401. break;
  402. case OIND:
  403. naddr(n->left, a);
  404. if(a->type == D_REG) {
  405. a->type = D_OREG;
  406. break;
  407. }
  408. if(a->type == D_CONST) {
  409. a->type = D_OREG;
  410. break;
  411. }
  412. goto bad;
  413. case OINDREG:
  414. a->type = D_OREG;
  415. a->sym = S;
  416. a->offset = n->xoffset;
  417. a->reg = n->reg;
  418. break;
  419. case ONAME:
  420. a->etype = n->etype;
  421. a->type = D_OREG;
  422. a->name = D_STATIC;
  423. a->sym = n->sym;
  424. a->offset = n->xoffset;
  425. if(n->class == CSTATIC)
  426. break;
  427. if(n->class == CEXTERN || n->class == CGLOBL) {
  428. a->name = D_EXTERN;
  429. break;
  430. }
  431. if(n->class == CAUTO) {
  432. a->name = D_AUTO;
  433. break;
  434. }
  435. if(n->class == CPARAM) {
  436. a->name = D_PARAM;
  437. break;
  438. }
  439. goto bad;
  440. case OCONST:
  441. a->sym = S;
  442. a->reg = NREG;
  443. if(typefd[n->type->etype]) {
  444. a->type = D_FCONST;
  445. a->dval = n->fconst;
  446. } else {
  447. a->type = D_CONST;
  448. a->offset = n->vconst;
  449. }
  450. break;
  451. case OADDR:
  452. naddr(n->left, a);
  453. if(a->type == D_OREG) {
  454. a->type = D_CONST;
  455. break;
  456. }
  457. goto bad;
  458. case OADD:
  459. if(n->left->op == OCONST) {
  460. naddr(n->left, a);
  461. v = a->offset;
  462. naddr(n->right, a);
  463. } else {
  464. naddr(n->right, a);
  465. v = a->offset;
  466. naddr(n->left, a);
  467. }
  468. a->offset += v;
  469. break;
  470. }
  471. }
  472. void
  473. gmovm(Node *f, Node *t)
  474. {
  475. gins(AMOVM, f, t); // always sets base register now
  476. }
  477. void
  478. gmove(Node *f, Node *t)
  479. {
  480. int ft, tt, a;
  481. Node nod;
  482. // prtree(f, "gmove src");
  483. // prtree(t, "gmove dst");
  484. ft = f->type->etype;
  485. tt = t->type->etype;
  486. if(ft == TDOUBLE && f->op == OCONST) {
  487. }
  488. if(ft == TFLOAT && f->op == OCONST) {
  489. }
  490. /*
  491. * a load --
  492. * put it into a register then
  493. * worry what to do with it.
  494. */
  495. if(f->op == ONAME || f->op == OINDREG || f->op == OIND) {
  496. switch(ft) {
  497. default:
  498. a = AMOVW;
  499. break;
  500. case TFLOAT:
  501. a = AMOVF;
  502. break;
  503. case TDOUBLE:
  504. a = AMOVD;
  505. break;
  506. case TCHAR:
  507. a = AMOVB;
  508. break;
  509. case TUCHAR:
  510. a = AMOVBU;
  511. break;
  512. case TSHORT:
  513. a = AMOVH;
  514. break;
  515. case TUSHORT:
  516. a = AMOVHU;
  517. break;
  518. }
  519. if(typechlp[ft] && typeilp[tt])
  520. regalloc(&nod, t, t);
  521. else
  522. regalloc(&nod, f, t);
  523. gins(a, f, &nod);
  524. gmove(&nod, t);
  525. regfree(&nod);
  526. return;
  527. }
  528. /*
  529. * a store --
  530. * put it into a register then
  531. * store it.
  532. */
  533. if(t->op == ONAME || t->op == OINDREG || t->op == OIND) {
  534. switch(tt) {
  535. default:
  536. a = AMOVW;
  537. break;
  538. case TUCHAR:
  539. a = AMOVBU;
  540. break;
  541. case TCHAR:
  542. a = AMOVB;
  543. break;
  544. case TUSHORT:
  545. a = AMOVHU;
  546. break;
  547. case TSHORT:
  548. a = AMOVH;
  549. break;
  550. case TFLOAT:
  551. a = AMOVF;
  552. break;
  553. case TVLONG:
  554. case TDOUBLE:
  555. a = AMOVD;
  556. break;
  557. }
  558. if(ft == tt)
  559. regalloc(&nod, t, f);
  560. else
  561. regalloc(&nod, t, Z);
  562. gmove(f, &nod);
  563. gins(a, &nod, t);
  564. regfree(&nod);
  565. return;
  566. }
  567. /*
  568. * type x type cross table
  569. */
  570. a = AGOK;
  571. switch(ft) {
  572. case TDOUBLE:
  573. case TVLONG:
  574. case TFLOAT:
  575. switch(tt) {
  576. case TDOUBLE:
  577. case TVLONG:
  578. a = AMOVD;
  579. if(ft == TFLOAT)
  580. a = AMOVFD;
  581. break;
  582. case TFLOAT:
  583. a = AMOVDF;
  584. if(ft == TFLOAT)
  585. a = AMOVF;
  586. break;
  587. case TINT:
  588. case TUINT:
  589. case TLONG:
  590. case TULONG:
  591. case TIND:
  592. case TSHORT:
  593. case TUSHORT:
  594. case TCHAR:
  595. case TUCHAR:
  596. a = AMOVDW;
  597. if(ft == TFLOAT)
  598. a = AMOVFW;
  599. break;
  600. }
  601. break;
  602. case TUINT:
  603. case TINT:
  604. case TULONG:
  605. case TLONG:
  606. case TIND:
  607. switch(tt) {
  608. case TDOUBLE:
  609. case TVLONG:
  610. gins(AMOVWD, f, t);
  611. if(ft == TULONG) {
  612. }
  613. return;
  614. case TFLOAT:
  615. gins(AMOVWF, f, t);
  616. if(ft == TULONG) {
  617. }
  618. return;
  619. case TINT:
  620. case TUINT:
  621. case TLONG:
  622. case TULONG:
  623. case TIND:
  624. case TSHORT:
  625. case TUSHORT:
  626. case TCHAR:
  627. case TUCHAR:
  628. a = AMOVW;
  629. break;
  630. }
  631. break;
  632. case TSHORT:
  633. switch(tt) {
  634. case TDOUBLE:
  635. case TVLONG:
  636. regalloc(&nod, f, Z);
  637. gins(AMOVH, f, &nod);
  638. gins(AMOVWD, &nod, t);
  639. regfree(&nod);
  640. return;
  641. case TFLOAT:
  642. regalloc(&nod, f, Z);
  643. gins(AMOVH, f, &nod);
  644. gins(AMOVWF, &nod, t);
  645. regfree(&nod);
  646. return;
  647. case TUINT:
  648. case TINT:
  649. case TULONG:
  650. case TLONG:
  651. case TIND:
  652. a = AMOVH;
  653. break;
  654. case TSHORT:
  655. case TUSHORT:
  656. case TCHAR:
  657. case TUCHAR:
  658. a = AMOVW;
  659. break;
  660. }
  661. break;
  662. case TUSHORT:
  663. switch(tt) {
  664. case TDOUBLE:
  665. case TVLONG:
  666. regalloc(&nod, f, Z);
  667. gins(AMOVHU, f, &nod);
  668. gins(AMOVWD, &nod, t);
  669. regfree(&nod);
  670. return;
  671. case TFLOAT:
  672. regalloc(&nod, f, Z);
  673. gins(AMOVHU, f, &nod);
  674. gins(AMOVWF, &nod, t);
  675. regfree(&nod);
  676. return;
  677. case TINT:
  678. case TUINT:
  679. case TLONG:
  680. case TULONG:
  681. case TIND:
  682. a = AMOVHU;
  683. break;
  684. case TSHORT:
  685. case TUSHORT:
  686. case TCHAR:
  687. case TUCHAR:
  688. a = AMOVW;
  689. break;
  690. }
  691. break;
  692. case TCHAR:
  693. switch(tt) {
  694. case TDOUBLE:
  695. case TVLONG:
  696. regalloc(&nod, f, Z);
  697. gins(AMOVB, f, &nod);
  698. gins(AMOVWD, &nod, t);
  699. regfree(&nod);
  700. return;
  701. case TFLOAT:
  702. regalloc(&nod, f, Z);
  703. gins(AMOVB, f, &nod);
  704. gins(AMOVWF, &nod, t);
  705. regfree(&nod);
  706. return;
  707. case TINT:
  708. case TUINT:
  709. case TLONG:
  710. case TULONG:
  711. case TIND:
  712. case TSHORT:
  713. case TUSHORT:
  714. a = AMOVB;
  715. break;
  716. case TCHAR:
  717. case TUCHAR:
  718. a = AMOVW;
  719. break;
  720. }
  721. break;
  722. case TUCHAR:
  723. switch(tt) {
  724. case TDOUBLE:
  725. case TVLONG:
  726. regalloc(&nod, f, Z);
  727. gins(AMOVBU, f, &nod);
  728. gins(AMOVWD, &nod, t);
  729. regfree(&nod);
  730. return;
  731. case TFLOAT:
  732. regalloc(&nod, f, Z);
  733. gins(AMOVBU, f, &nod);
  734. gins(AMOVWF, &nod, t);
  735. regfree(&nod);
  736. return;
  737. case TINT:
  738. case TUINT:
  739. case TLONG:
  740. case TULONG:
  741. case TIND:
  742. case TSHORT:
  743. case TUSHORT:
  744. a = AMOVBU;
  745. break;
  746. case TCHAR:
  747. case TUCHAR:
  748. a = AMOVW;
  749. break;
  750. }
  751. break;
  752. }
  753. if(a == AGOK)
  754. diag(Z, "bad opcode in gmove %T -> %T", f->type, t->type);
  755. if(a == AMOVW || a == AMOVF || a == AMOVD)
  756. if(samaddr(f, t))
  757. return;
  758. gins(a, f, t);
  759. }
  760. void
  761. gins(int a, Node *f, Node *t)
  762. {
  763. nextpc();
  764. p->as = a;
  765. if(f != Z)
  766. naddr(f, &p->from);
  767. if(t != Z)
  768. naddr(t, &p->to);
  769. if(debug['g'])
  770. print("%P\n", p);
  771. }
  772. void
  773. gopcode(int o, Node *f1, Node *f2, Node *t)
  774. {
  775. int a, et;
  776. Adr ta;
  777. et = TLONG;
  778. if(f1 != Z && f1->type != T)
  779. et = f1->type->etype;
  780. a = AGOK;
  781. switch(o) {
  782. case OAS:
  783. gmove(f1, t);
  784. return;
  785. case OASADD:
  786. case OADD:
  787. a = AADD;
  788. if(et == TFLOAT)
  789. a = AADDF;
  790. else
  791. if(et == TDOUBLE || et == TVLONG)
  792. a = AADDD;
  793. break;
  794. case OASSUB:
  795. case OSUB:
  796. a = ASUB;
  797. if(et == TFLOAT)
  798. a = ASUBF;
  799. else
  800. if(et == TDOUBLE || et == TVLONG)
  801. a = ASUBD;
  802. break;
  803. case OASOR:
  804. case OOR:
  805. a = AORR;
  806. break;
  807. case OASAND:
  808. case OAND:
  809. a = AAND;
  810. break;
  811. case OASXOR:
  812. case OXOR:
  813. a = AEOR;
  814. break;
  815. case OASLSHR:
  816. case OLSHR:
  817. a = ASRL;
  818. break;
  819. case OASASHR:
  820. case OASHR:
  821. a = ASRA;
  822. break;
  823. case OASASHL:
  824. case OASHL:
  825. a = ASLL;
  826. break;
  827. case OFUNC:
  828. a = ABL;
  829. break;
  830. case OASMUL:
  831. case OMUL:
  832. a = AMUL;
  833. if(et == TFLOAT)
  834. a = AMULF;
  835. else
  836. if(et == TDOUBLE || et == TVLONG)
  837. a = AMULD;
  838. break;
  839. case OASDIV:
  840. case ODIV:
  841. a = ADIV;
  842. if(et == TFLOAT)
  843. a = ADIVF;
  844. else
  845. if(et == TDOUBLE || et == TVLONG)
  846. a = ADIVD;
  847. break;
  848. case OASMOD:
  849. case OMOD:
  850. a = AMOD;
  851. break;
  852. case OASLMUL:
  853. case OLMUL:
  854. a = AMULU;
  855. break;
  856. case OASLMOD:
  857. case OLMOD:
  858. a = AMODU;
  859. break;
  860. case OASLDIV:
  861. case OLDIV:
  862. a = ADIVU;
  863. break;
  864. case OEQ:
  865. case ONE:
  866. case OLT:
  867. case OLE:
  868. case OGE:
  869. case OGT:
  870. case OLO:
  871. case OLS:
  872. case OHS:
  873. case OHI:
  874. a = ACMP;
  875. if(et == TFLOAT)
  876. a = ACMPF;
  877. else
  878. if(et == TDOUBLE || et == TVLONG)
  879. a = ACMPD;
  880. nextpc();
  881. p->as = a;
  882. naddr(f1, &p->from);
  883. /*
  884. if(a == ACMP && f1->op == OCONST && p->from.offset < 0) {
  885. p->as = ACMN;
  886. p->from.offset = -p->from.offset;
  887. }
  888. */
  889. raddr(f2, p); // expects it to be a register
  890. switch(o) {
  891. case OEQ:
  892. a = ABEQ;
  893. break;
  894. case ONE:
  895. a = ABNE;
  896. break;
  897. case OLT:
  898. a = ABLT;
  899. break;
  900. case OLE:
  901. a = ABLE;
  902. break;
  903. case OGE:
  904. a = ABGE;
  905. break;
  906. case OGT:
  907. a = ABGT;
  908. break;
  909. case OLO:
  910. a = ABLO;
  911. break;
  912. case OLS:
  913. a = ABLS;
  914. break;
  915. case OHS:
  916. a = ABHS;
  917. break;
  918. case OHI:
  919. a = ABHI;
  920. break;
  921. }
  922. f1 = Z;
  923. f2 = Z;
  924. break;
  925. }
  926. if(a == AGOK)
  927. diag(Z, "bad in gopcode %O", o);
  928. nextpc();
  929. p->as = a;
  930. if(f1 != Z)
  931. naddr(f1, &p->from);
  932. if(f2 != Z) {
  933. naddr(f2, &ta);
  934. p->reg = ta.reg;
  935. }
  936. if(t != Z)
  937. naddr(t, &p->to);
  938. if(debug['g'])
  939. print("%P\n", p);
  940. }
  941. /* put f1 in a register first */
  942. void
  943. gopcode2(int o, Node *f1, Node *f2, Node *t)
  944. {
  945. Node nod;
  946. if(f2 != Z)
  947. diag(Z, "bad parameter in gopcode2");
  948. // regalloc(&nod, t, Z);
  949. nodreg(&nod, t, REGTMPT);
  950. gopcode(OAS, f1, Z, &nod);
  951. gopcode(o, &nod, Z, t);
  952. // regfree(&nod);
  953. }
  954. samaddr(Node *f, Node *t)
  955. {
  956. if(f->op != t->op)
  957. return 0;
  958. switch(f->op) {
  959. case OREGISTER:
  960. if(f->reg != t->reg)
  961. break;
  962. return 1;
  963. }
  964. return 0;
  965. }
  966. void
  967. gbranch(int o)
  968. {
  969. int a;
  970. a = AGOK;
  971. switch(o) {
  972. case ORETURN:
  973. a = ARET;
  974. break;
  975. case OGOTO:
  976. a = AB;
  977. break;
  978. }
  979. nextpc();
  980. if(a == AGOK) {
  981. diag(Z, "bad in gbranch %O", o);
  982. nextpc();
  983. }
  984. p->as = a;
  985. }
  986. void
  987. patch(Prog *op, long pc)
  988. {
  989. op->to.offset = pc;
  990. op->to.type = D_BRANCH;
  991. }
  992. void
  993. gpseudo(int a, Sym *s, Node *n)
  994. {
  995. nextpc();
  996. p->as = a;
  997. p->from.type = D_OREG;
  998. p->from.sym = s;
  999. p->from.name = D_EXTERN;
  1000. if(a == ATEXT)
  1001. p->reg = (profileflg ? 0 : NOPROF);
  1002. if(s->class == CSTATIC)
  1003. p->from.name = D_STATIC;
  1004. naddr(n, &p->to);
  1005. if(a == ADATA || a == AGLOBL)
  1006. pc--;
  1007. }
  1008. int
  1009. sconst(Node *n)
  1010. {
  1011. vlong vv;
  1012. if(n->op == OCONST) {
  1013. if(!typefd[n->type->etype]) {
  1014. vv = n->vconst;
  1015. if(vv >= (vlong)0 && vv < (vlong)256)
  1016. return 1;
  1017. /*
  1018. * should be specialised for constant values which will
  1019. * fit in different instructionsl; for now, let 5l
  1020. * sort it out
  1021. */
  1022. return 1;
  1023. }
  1024. }
  1025. return 0;
  1026. }
  1027. int
  1028. sval(long v)
  1029. {
  1030. if(v >= -32768 && v < 32768)
  1031. return 1;
  1032. return 0;
  1033. }
  1034. long
  1035. exreg(Type *t)
  1036. {
  1037. long o;
  1038. if(typechlp[t->etype]) {
  1039. if(exregoffset <= NREG-1)
  1040. return 0;
  1041. o = exregoffset;
  1042. exregoffset--;
  1043. return o;
  1044. }
  1045. if(typefd[t->etype]) {
  1046. if(exfregoffset <= NFREG-1)
  1047. return 0;
  1048. o = exfregoffset + NREG;
  1049. exfregoffset--;
  1050. return o;
  1051. }
  1052. return 0;
  1053. }
  1054. schar ewidth[NTYPE] =
  1055. {
  1056. -1, /* [TXXX] */
  1057. SZ_CHAR, /* [TCHAR] */
  1058. SZ_CHAR, /* [TUCHAR] */
  1059. SZ_SHORT, /* [TSHORT] */
  1060. SZ_SHORT, /* [TUSHORT] */
  1061. SZ_INT, /* [TINT] */
  1062. SZ_INT, /* [TUINT] */
  1063. SZ_LONG, /* [TLONG] */
  1064. SZ_LONG, /* [TULONG] */
  1065. SZ_VLONG, /* [TVLONG] */
  1066. SZ_VLONG, /* [TUVLONG] */
  1067. SZ_FLOAT, /* [TFLOAT] */
  1068. SZ_DOUBLE, /* [TDOUBLE] */
  1069. SZ_IND, /* [TIND] */
  1070. 0, /* [TFUNC] */
  1071. -1, /* [TARRAY] */
  1072. 0, /* [TVOID] */
  1073. -1, /* [TSTRUCT] */
  1074. -1, /* [TUNION] */
  1075. SZ_INT, /* [TENUM] */
  1076. };
  1077. long ncast[NTYPE] =
  1078. {
  1079. 0, /* [TXXX] */
  1080. BCHAR|BUCHAR, /* [TCHAR] */
  1081. BCHAR|BUCHAR, /* [TUCHAR] */
  1082. BSHORT|BUSHORT, /* [TSHORT] */
  1083. BSHORT|BUSHORT, /* [TUSHORT] */
  1084. BINT|BUINT|BLONG|BULONG|BIND, /* [TINT] */
  1085. BINT|BUINT|BLONG|BULONG|BIND, /* [TUINT] */
  1086. BINT|BUINT|BLONG|BULONG|BIND, /* [TLONG] */
  1087. BINT|BUINT|BLONG|BULONG|BIND, /* [TULONG] */
  1088. BVLONG|BUVLONG, /* [TVLONG] */
  1089. BVLONG|BUVLONG, /* [TUVLONG] */
  1090. BFLOAT, /* [TFLOAT] */
  1091. BDOUBLE, /* [TDOUBLE] */
  1092. BLONG|BULONG|BIND, /* [TIND] */
  1093. 0, /* [TFUNC] */
  1094. 0, /* [TARRAY] */
  1095. 0, /* [TVOID] */
  1096. BSTRUCT, /* [TSTRUCT] */
  1097. BUNION, /* [TUNION] */
  1098. 0, /* [TENUM] */
  1099. };