PageRenderTime 28ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/utils/qc/txt.c

https://bitbucket.org/floren/inferno/
C | 1747 lines | 1584 code | 136 blank | 27 comment | 445 complexity | 26082b611ed25536dc65667ccabb01b1 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, MPL-2.0-no-copyleft-exception
  1. #include "gc.h"
  2. static int resvreg[nelem(reg)];
  3. static void gopcode64(int, Node*, Node*, Node*);
  4. static void gori64(int, Node*, Node*, Node*);
  5. static void gandi64(int, Node*, Node*, Node*);
  6. void
  7. ginit(void)
  8. {
  9. Type *t;
  10. thechar = 'q';
  11. thestring = "power";
  12. exregoffset = REGEXT;
  13. exfregoffset = FREGEXT;
  14. listinit();
  15. nstring = 0;
  16. mnstring = 0;
  17. nrathole = 0;
  18. pc = 0;
  19. breakpc = -1;
  20. continpc = -1;
  21. cases = C;
  22. firstp = P;
  23. lastp = P;
  24. tfield = types[TLONG];
  25. zprog.link = P;
  26. zprog.as = AGOK;
  27. zprog.reg = NREG;
  28. zprog.from.type = D_NONE;
  29. zprog.from.name = D_NONE;
  30. zprog.from.reg = NREG;
  31. zprog.from3 = zprog.from;
  32. zprog.to = zprog.from;
  33. regnode.op = OREGISTER;
  34. regnode.class = CEXREG;
  35. regnode.reg = 0;
  36. regnode.complex = 0;
  37. regnode.addable = 11;
  38. regnode.type = types[TLONG];
  39. constnode.op = OCONST;
  40. constnode.class = CXXX;
  41. constnode.complex = 0;
  42. constnode.addable = 20;
  43. constnode.type = types[TLONG];
  44. fconstnode.op = OCONST;
  45. fconstnode.class = CXXX;
  46. fconstnode.complex = 0;
  47. fconstnode.addable = 20;
  48. fconstnode.type = types[TDOUBLE];
  49. nodsafe = new(ONAME, Z, Z);
  50. nodsafe->sym = slookup(".safe");
  51. nodsafe->type = types[TINT];
  52. nodsafe->etype = types[TINT]->etype;
  53. nodsafe->class = CAUTO;
  54. complex(nodsafe);
  55. t = typ(TARRAY, types[TCHAR]);
  56. symrathole = slookup(".rathole");
  57. symrathole->class = CGLOBL;
  58. symrathole->type = t;
  59. nodrat = new(ONAME, Z, Z);
  60. nodrat->sym = symrathole;
  61. nodrat->type = types[TIND];
  62. nodrat->etype = TVOID;
  63. nodrat->class = CGLOBL;
  64. complex(nodrat);
  65. nodrat->type = t;
  66. com64init();
  67. memset(reg, 0, sizeof(reg));
  68. reg[REGZERO] = 1; /* don't use */
  69. reg[REGTMP] = 1;
  70. reg[FREGCVI+NREG] = 1;
  71. reg[FREGZERO+NREG] = 1;
  72. reg[FREGHALF+NREG] = 1;
  73. reg[FREGONE+NREG] = 1;
  74. reg[FREGTWO+NREG] = 1;
  75. memmove(resvreg, reg, sizeof(reg));
  76. }
  77. void
  78. gclean(void)
  79. {
  80. int i;
  81. Sym *s;
  82. for(i=0; i<NREG; i++)
  83. if(reg[i] && !resvreg[i])
  84. diag(Z, "reg %d left allocated", i);
  85. for(i=NREG; i<NREG+NREG; i++)
  86. if(reg[i] && !resvreg[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(typesuv[n->type->etype]) {
  161. regaalloc(tn2, n);
  162. if(n->complex >= FNX) {
  163. cgen(*fnxp, tn2);
  164. (*fnxp)++;
  165. } else
  166. cgen(n, tn2);
  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. nod32const(vlong v)
  195. {
  196. constnode.vconst = v & MASK(32);
  197. return &constnode;
  198. }
  199. Node*
  200. nodconst(long v)
  201. {
  202. constnode.vconst = v;
  203. return &constnode;
  204. }
  205. Node*
  206. nodfconst(double d)
  207. {
  208. fconstnode.fconst = d;
  209. return &fconstnode;
  210. }
  211. void
  212. nodreg(Node *n, Node *nn, int reg)
  213. {
  214. *n = regnode;
  215. n->reg = reg;
  216. n->type = nn->type;
  217. n->lineno = nn->lineno;
  218. }
  219. void
  220. regret(Node *n, Node *nn)
  221. {
  222. int r;
  223. r = REGRET;
  224. if(typefd[nn->type->etype])
  225. r = FREGRET+NREG;
  226. nodreg(n, nn, r);
  227. reg[r]++;
  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<NREG; i++) {
  251. if(j >= NREG)
  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. if(o != Z && o->op == OREGISTER) {
  264. i = o->reg;
  265. if(i >= NREG && i < NREG+NREG)
  266. goto out;
  267. }
  268. j = lasti + NREG;
  269. for(i=NREG; i<NREG+NREG; i++) {
  270. if(j >= NREG+NREG)
  271. j = NREG;
  272. if(reg[j] == 0) {
  273. i = j;
  274. goto out;
  275. }
  276. j++;
  277. }
  278. diag(tn, "out of float registers");
  279. goto err;
  280. case TVLONG:
  281. case TUVLONG:
  282. n->op = OREGPAIR;
  283. n->complex = 0; /* already in registers */
  284. n->addable = 11;
  285. n->type = tn->type;
  286. n->lineno = nearln;
  287. n->left = alloc(sizeof(Node));
  288. n->right = alloc(sizeof(Node));
  289. if(o != Z && o->op == OREGPAIR) {
  290. regalloc(n->left, &regnode, o->left);
  291. regalloc(n->right, &regnode, o->right);
  292. } else {
  293. regalloc(n->left, &regnode, Z);
  294. regalloc(n->right, &regnode, Z);
  295. }
  296. n->right->type = types[TULONG];
  297. if(tn->type->etype == TUVLONG)
  298. n->left->type = types[TULONG]; /* TO DO: is this a bad idea? */
  299. return;
  300. }
  301. diag(tn, "unknown type in regalloc: %T", tn->type);
  302. err:
  303. i = 0;
  304. out:
  305. if(i)
  306. reg[i]++;
  307. lasti++;
  308. if(lasti >= 5)
  309. lasti = 0;
  310. nodreg(n, tn, i);
  311. }
  312. void
  313. regialloc(Node *n, Node *tn, Node *o)
  314. {
  315. Node nod;
  316. nod = *tn;
  317. nod.type = types[TIND];
  318. regalloc(n, &nod, o);
  319. }
  320. void
  321. regfree(Node *n)
  322. {
  323. int i;
  324. if(n->op == OREGPAIR) {
  325. regfree(n->left);
  326. regfree(n->right);
  327. return;
  328. }
  329. i = 0;
  330. if(n->op != OREGISTER && n->op != OINDREG)
  331. goto err;
  332. i = n->reg;
  333. if(i < 0 || i >= sizeof(reg))
  334. goto err;
  335. if(reg[i] <= 0)
  336. goto err;
  337. reg[i]--;
  338. return;
  339. err:
  340. diag(n, "error in regfree: %d [%d]", i, reg[i]);
  341. prtree(n, "regfree");
  342. }
  343. void
  344. regsalloc(Node *n, Node *nn)
  345. {
  346. cursafe = align(cursafe+stkoff, nn->type, Aaut3)-stkoff;
  347. maxargsafe = maxround(maxargsafe, cursafe+curarg);
  348. // if(nn->type->etype == TDOUBLE || nn->type->etype == TVLONG){
  349. // extern int hasdoubled;
  350. // fprint(2, "stkoff=%ld cursafe=%ld curarg=%ld %d\n", stkoff, cursafe, curarg, hasdoubled);
  351. // }
  352. *n = *nodsafe;
  353. n->xoffset = -(stkoff + cursafe);
  354. n->type = nn->type;
  355. n->etype = nn->type->etype;
  356. n->lineno = nn->lineno;
  357. }
  358. void
  359. regaalloc1(Node *n, Node *nn)
  360. {
  361. nodreg(n, nn, REGARG);
  362. reg[REGARG]++;
  363. curarg = align(curarg, nn->type, Aarg1);
  364. curarg = align(curarg, nn->type, Aarg2);
  365. maxargsafe = maxround(maxargsafe, cursafe+curarg);
  366. }
  367. void
  368. regaalloc(Node *n, Node *nn)
  369. {
  370. curarg = align(curarg, nn->type, Aarg1);
  371. *n = *nn;
  372. n->op = OINDREG;
  373. n->reg = REGSP;
  374. n->xoffset = curarg + SZ_LONG;
  375. n->complex = 0;
  376. n->addable = 20;
  377. curarg = align(curarg, nn->type, Aarg2);
  378. maxargsafe = maxround(maxargsafe, cursafe+curarg);
  379. }
  380. void
  381. regind(Node *n, Node *nn)
  382. {
  383. if(n->op != OREGISTER) {
  384. diag(n, "regind not OREGISTER");
  385. return;
  386. }
  387. n->op = OINDREG;
  388. n->type = nn->type;
  389. }
  390. void
  391. raddr(Node *n, Prog *p)
  392. {
  393. Adr a;
  394. naddr(n, &a);
  395. if(R0ISZERO && a.type == D_CONST && a.offset == 0) {
  396. a.type = D_REG;
  397. a.reg = REGZERO;
  398. }
  399. if(a.type != D_REG && a.type != D_FREG) {
  400. if(n)
  401. diag(n, "bad in raddr: %O", n->op);
  402. else
  403. diag(n, "bad in raddr: <null>");
  404. p->reg = NREG;
  405. } else
  406. p->reg = a.reg;
  407. }
  408. void
  409. naddr(Node *n, Adr *a)
  410. {
  411. long v;
  412. a->type = D_NONE;
  413. if(n == Z)
  414. return;
  415. switch(n->op) {
  416. default:
  417. bad:
  418. diag(n, "bad in naddr: %O", n->op);
  419. break;
  420. case OREGISTER:
  421. a->type = D_REG;
  422. a->sym = S;
  423. a->reg = n->reg;
  424. if(a->reg >= NREG) {
  425. a->type = D_FREG;
  426. a->reg -= NREG;
  427. }
  428. break;
  429. case OIND:
  430. naddr(n->left, a);
  431. a->offset += n->xoffset; /* little hack for reglcgenv */
  432. if(a->type == D_REG) {
  433. a->type = D_OREG;
  434. break;
  435. }
  436. if(a->type == D_CONST) {
  437. a->type = D_OREG;
  438. break;
  439. }
  440. goto bad;
  441. case OINDREG:
  442. a->type = D_OREG;
  443. a->sym = S;
  444. a->offset = n->xoffset;
  445. a->reg = n->reg;
  446. break;
  447. case ONAME:
  448. a->etype = n->etype;
  449. a->type = D_OREG;
  450. a->name = D_STATIC;
  451. a->sym = n->sym;
  452. a->offset = n->xoffset;
  453. if(n->class == CSTATIC)
  454. break;
  455. if(n->class == CEXTERN || n->class == CGLOBL) {
  456. a->name = D_EXTERN;
  457. break;
  458. }
  459. if(n->class == CAUTO) {
  460. a->name = D_AUTO;
  461. break;
  462. }
  463. if(n->class == CPARAM) {
  464. a->name = D_PARAM;
  465. break;
  466. }
  467. goto bad;
  468. case OCONST:
  469. a->sym = S;
  470. a->reg = NREG;
  471. if(typefd[n->type->etype]) {
  472. a->type = D_FCONST;
  473. a->dval = n->fconst;
  474. } else {
  475. a->type = D_CONST;
  476. a->offset = n->vconst;
  477. }
  478. break;
  479. case OADDR:
  480. naddr(n->left, a);
  481. if(a->type == D_OREG) {
  482. a->type = D_CONST;
  483. break;
  484. }
  485. goto bad;
  486. case OADD:
  487. if(n->left->op == OCONST) {
  488. naddr(n->left, a);
  489. v = a->offset;
  490. naddr(n->right, a);
  491. } else {
  492. naddr(n->right, a);
  493. v = a->offset;
  494. naddr(n->left, a);
  495. }
  496. a->offset += v;
  497. break;
  498. }
  499. }
  500. void
  501. gloadhi(Node *f, Node *t, int c)
  502. {
  503. Type *ot;
  504. if(f->op == OCONST){
  505. f = nodconst((long)(f->vconst>>32));
  506. if(c==1 && sconst(f) || c==2 && uconst(f)){
  507. if(t->op == OREGISTER)
  508. regfree(t);
  509. *t = *f;
  510. return;
  511. }
  512. }
  513. if(f->op == OREGPAIR) {
  514. gmove(f->left, t);
  515. return;
  516. }
  517. ot = f->type;
  518. f->type = types[TLONG];
  519. gmove(f, t);
  520. f->type = ot;
  521. }
  522. void
  523. gloadlo(Node *f, Node *t, int c)
  524. {
  525. Type *ot;
  526. if(f->op == OCONST){
  527. f = nodconst((long)f->vconst);
  528. if(c && uconst(f)){
  529. if(t->op == OREGISTER)
  530. regfree(t);
  531. *t = *f;
  532. return;
  533. }
  534. }
  535. if(f->op == OREGPAIR) {
  536. gmove(f->right, t);
  537. return;
  538. }
  539. ot = f->type;
  540. f->type = types[TLONG];
  541. f->xoffset += SZ_LONG;
  542. if(0){
  543. prtree(f, "gloadlo f"); prtree(t, "gloadlo t");
  544. }
  545. gmove(f, t);
  546. f->xoffset -= SZ_LONG;
  547. f->type = ot;
  548. }
  549. void
  550. fop(int as, int f1, int f2, Node *t)
  551. {
  552. Node nod1, nod2, nod3;
  553. nodreg(&nod1, t, NREG+f1);
  554. nodreg(&nod2, t, NREG+f2);
  555. regalloc(&nod3, t, t);
  556. gopcode(as, &nod1, &nod2, &nod3);
  557. gmove(&nod3, t);
  558. regfree(&nod3);
  559. }
  560. void
  561. gmove(Node *f, Node *t)
  562. {
  563. int ft, tt, a;
  564. Node nod, fxc0, fxc1, fxc2, fxrat;
  565. Prog *p1;
  566. double d;
  567. ft = f->type->etype;
  568. tt = t->type->etype;
  569. if(ft == TDOUBLE && f->op == OCONST) {
  570. d = f->fconst;
  571. if(d == 0.0) {
  572. a = FREGZERO;
  573. goto ffreg;
  574. }
  575. if(d == 0.5) {
  576. a = FREGHALF;
  577. goto ffreg;
  578. }
  579. if(d == 1.0) {
  580. a = FREGONE;
  581. goto ffreg;
  582. }
  583. if(d == 2.0) {
  584. a = FREGTWO;
  585. goto ffreg;
  586. }
  587. if(d == -.5) {
  588. fop(OSUB, FREGHALF, FREGZERO, t);
  589. return;
  590. }
  591. if(d == -1.0) {
  592. fop(OSUB, FREGONE, FREGZERO, t);
  593. return;
  594. }
  595. if(d == -2.0) {
  596. fop(OSUB, FREGTWO, FREGZERO, t);
  597. return;
  598. }
  599. if(d == 1.5) {
  600. fop(OADD, FREGONE, FREGHALF, t);
  601. return;
  602. }
  603. if(d == 2.5) {
  604. fop(OADD, FREGTWO, FREGHALF, t);
  605. return;
  606. }
  607. if(d == 3.0) {
  608. fop(OADD, FREGTWO, FREGONE, t);
  609. return;
  610. }
  611. }
  612. if(ft == TFLOAT && f->op == OCONST) {
  613. d = f->fconst;
  614. if(d == 0) {
  615. a = FREGZERO;
  616. ffreg:
  617. nodreg(&nod, f, NREG+a);
  618. gmove(&nod, t);
  619. return;
  620. }
  621. }
  622. if((ft == TVLONG || ft == TUVLONG) && f->op == OCONST && t->op == OREGPAIR) {
  623. if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
  624. gmove(nod32const(f->vconst>>32), t->left);
  625. else
  626. gmove(nod32const(f->vconst), t->left);
  627. if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
  628. gmove(nod32const(f->vconst), t->right);
  629. else
  630. gmove(nod32const(f->vconst>>32), t->right);
  631. return;
  632. }
  633. /*
  634. * a load --
  635. * put it into a register then
  636. * worry what to do with it.
  637. */
  638. if(f->op == ONAME || f->op == OINDREG || f->op == OIND) {
  639. switch(ft) {
  640. default:
  641. a = AMOVW;
  642. break;
  643. case TFLOAT:
  644. a = AFMOVS;
  645. break;
  646. case TDOUBLE:
  647. a = AFMOVD;
  648. break;
  649. case TCHAR:
  650. a = AMOVB;
  651. break;
  652. case TUCHAR:
  653. a = AMOVBZ;
  654. break;
  655. case TSHORT:
  656. a = AMOVH;
  657. break;
  658. case TUSHORT:
  659. a = AMOVHZ;
  660. break;
  661. }
  662. if(typev[ft]) {
  663. if(typev[tt]) {
  664. regalloc(&nod, f, t);
  665. /* low order first, because its value will be used first */
  666. f->xoffset += SZ_LONG;
  667. gins(AMOVW, f, nod.right);
  668. f->xoffset -= SZ_LONG;
  669. gins(AMOVW, f, nod.left);
  670. } else {
  671. /* assumed not float or double */
  672. regalloc(&nod, &regnode, t);
  673. f->xoffset += SZ_LONG;
  674. gins(AMOVW, f, &nod);
  675. f->xoffset -= SZ_LONG;
  676. }
  677. } else {
  678. regalloc(&nod, f, t);
  679. gins(a, f, &nod);
  680. }
  681. gmove(&nod, t);
  682. regfree(&nod);
  683. return;
  684. }
  685. /*
  686. * a store --
  687. * put it into a register then
  688. * store it.
  689. */
  690. if(t->op == ONAME || t->op == OINDREG || t->op == OIND) {
  691. switch(tt) {
  692. default:
  693. a = AMOVW;
  694. break;
  695. case TUCHAR:
  696. a = AMOVBZ;
  697. break;
  698. case TCHAR:
  699. a = AMOVB;
  700. break;
  701. case TUSHORT:
  702. a = AMOVHZ;
  703. break;
  704. case TSHORT:
  705. a = AMOVH;
  706. break;
  707. case TFLOAT:
  708. a = AFMOVS;
  709. break;
  710. case TDOUBLE:
  711. a = AFMOVD;
  712. break;
  713. }
  714. if(R0ISZERO && !typefd[ft] && vconst(f) == 0) {
  715. gins(a, f, t);
  716. if(typev[tt]) {
  717. t->xoffset += SZ_LONG;
  718. gins(a, f, t);
  719. t->xoffset -= SZ_LONG;
  720. }
  721. return;
  722. }
  723. if(ft == tt)
  724. regalloc(&nod, t, f);
  725. else
  726. regalloc(&nod, t, Z);
  727. gmove(f, &nod);
  728. if(typev[tt]) {
  729. t->xoffset += SZ_LONG;
  730. gins(a, nod.right, t);
  731. t->xoffset -= SZ_LONG;
  732. gins(a, nod.left, t);
  733. } else
  734. gins(a, &nod, t);
  735. regfree(&nod);
  736. return;
  737. }
  738. /*
  739. * type x type cross table
  740. */
  741. a = AGOK;
  742. switch(ft) {
  743. case TDOUBLE:
  744. case TFLOAT:
  745. switch(tt) {
  746. case TDOUBLE:
  747. a = AFMOVD;
  748. if(ft == TFLOAT)
  749. a = AFMOVS; /* AFMOVSD */
  750. break;
  751. case TFLOAT:
  752. a = AFRSP;
  753. if(ft == TFLOAT)
  754. a = AFMOVS;
  755. break;
  756. case TINT:
  757. case TUINT:
  758. case TLONG:
  759. case TULONG:
  760. case TIND:
  761. case TSHORT:
  762. case TUSHORT:
  763. case TCHAR:
  764. case TUCHAR:
  765. /* BUG: not right for unsigned long */
  766. regalloc(&nod, f, Z); /* should be type float */
  767. regsalloc(&fxrat, &fconstnode);
  768. gins(AFCTIWZ, f, &nod);
  769. gins(AFMOVD, &nod, &fxrat);
  770. regfree(&nod);
  771. fxrat.type = nodrat->type;
  772. fxrat.etype = nodrat->etype;
  773. fxrat.xoffset += 4;
  774. gins(AMOVW, &fxrat, t);
  775. gmove(t, t);
  776. return;
  777. }
  778. break;
  779. case TINT:
  780. case TUINT:
  781. case TLONG:
  782. case TULONG:
  783. case TIND:
  784. switch(tt) {
  785. case TDOUBLE:
  786. case TFLOAT:
  787. goto fxtofl;
  788. case TINT:
  789. case TUINT:
  790. case TLONG:
  791. case TULONG:
  792. case TIND:
  793. case TSHORT:
  794. case TUSHORT:
  795. case TCHAR:
  796. case TUCHAR:
  797. a = AMOVW;
  798. break;
  799. }
  800. break;
  801. case TSHORT:
  802. switch(tt) {
  803. case TDOUBLE:
  804. case TFLOAT:
  805. goto fxtofl;
  806. case TINT:
  807. case TUINT:
  808. case TLONG:
  809. case TULONG:
  810. case TIND:
  811. a = AMOVH;
  812. break;
  813. case TSHORT:
  814. case TUSHORT:
  815. case TCHAR:
  816. case TUCHAR:
  817. a = AMOVW;
  818. break;
  819. }
  820. break;
  821. case TUSHORT:
  822. switch(tt) {
  823. case TDOUBLE:
  824. case TFLOAT:
  825. goto fxtofl;
  826. case TINT:
  827. case TUINT:
  828. case TLONG:
  829. case TULONG:
  830. case TIND:
  831. a = AMOVHZ;
  832. break;
  833. case TSHORT:
  834. case TUSHORT:
  835. case TCHAR:
  836. case TUCHAR:
  837. a = AMOVW;
  838. break;
  839. }
  840. break;
  841. case TCHAR:
  842. switch(tt) {
  843. case TDOUBLE:
  844. case TFLOAT:
  845. goto fxtofl;
  846. case TINT:
  847. case TUINT:
  848. case TLONG:
  849. case TULONG:
  850. case TIND:
  851. case TSHORT:
  852. case TUSHORT:
  853. a = AMOVB;
  854. break;
  855. case TCHAR:
  856. case TUCHAR:
  857. a = AMOVW;
  858. break;
  859. }
  860. break;
  861. case TUCHAR:
  862. switch(tt) {
  863. case TDOUBLE:
  864. case TFLOAT:
  865. fxtofl:
  866. /*
  867. * rat[0] = 0x43300000; rat[1] = f^0x80000000;
  868. * t = *(double*)rat - FREGCVI;
  869. * is-unsigned(t) => if(t<0) t += 2^32;
  870. * could be streamlined for int-to-float
  871. */
  872. regalloc(&fxc0, f, Z);
  873. regalloc(&fxc2, f, Z);
  874. regsalloc(&fxrat, &fconstnode); /* should be type float */
  875. gins(AMOVW, nodconst(0x43300000L), &fxc0);
  876. gins(AMOVW, f, &fxc2);
  877. gins(AMOVW, &fxc0, &fxrat);
  878. gins(AXOR, nodconst(0x80000000L), &fxc2);
  879. fxc1 = fxrat;
  880. fxc1.type = nodrat->type;
  881. fxc1.etype = nodrat->etype;
  882. fxc1.xoffset += SZ_LONG;
  883. gins(AMOVW, &fxc2, &fxc1);
  884. regfree(&fxc2);
  885. regfree(&fxc0);
  886. regalloc(&nod, t, t); /* should be type float */
  887. gins(AFMOVD, &fxrat, &nod);
  888. nodreg(&fxc1, t, NREG+FREGCVI);
  889. gins(AFSUB, &fxc1, &nod);
  890. a = AFMOVD;
  891. if(tt == TFLOAT)
  892. a = AFRSP;
  893. gins(a, &nod, t);
  894. regfree(&nod);
  895. if(ft == TULONG) {
  896. regalloc(&nod, t, Z);
  897. if(tt == TFLOAT) {
  898. gins(AFCMPU, t, Z);
  899. p->to.type = D_FREG;
  900. p->to.reg = FREGZERO;
  901. gins(ABGE, Z, Z);
  902. p1 = p;
  903. gins(AFMOVS, nodfconst(4294967296.), &nod);
  904. gins(AFADDS, &nod, t);
  905. } else {
  906. gins(AFCMPU, t, Z);
  907. p->to.type = D_FREG;
  908. p->to.reg = FREGZERO;
  909. gins(ABGE, Z, Z);
  910. p1 = p;
  911. gins(AFMOVD, nodfconst(4294967296.), &nod);
  912. gins(AFADD, &nod, t);
  913. }
  914. patch(p1, pc);
  915. regfree(&nod);
  916. }
  917. return;
  918. case TINT:
  919. case TUINT:
  920. case TLONG:
  921. case TULONG:
  922. case TIND:
  923. case TSHORT:
  924. case TUSHORT:
  925. a = AMOVBZ;
  926. break;
  927. case TCHAR:
  928. case TUCHAR:
  929. a = AMOVW;
  930. break;
  931. }
  932. break;
  933. case TVLONG:
  934. case TUVLONG:
  935. switch(tt) {
  936. case TVLONG:
  937. case TUVLONG:
  938. a = AMOVW;
  939. break;
  940. }
  941. break;
  942. }
  943. if(a == AGOK)
  944. diag(Z, "bad opcode in gmove %T -> %T", f->type, t->type);
  945. if(a == AMOVW || a == AFMOVS || a == AFMOVD)
  946. if(samaddr(f, t))
  947. return;
  948. if(typev[ft]) {
  949. if(f->op != OREGPAIR || t->op != OREGPAIR)
  950. diag(Z, "bad vlong in gmove (%O->%O)", f->op, t->op);
  951. gins(a, f->left, t->left);
  952. gins(a, f->right, t->right);
  953. } else
  954. gins(a, f, t);
  955. }
  956. void
  957. gins(int a, Node *f, Node *t)
  958. {
  959. nextpc();
  960. p->as = a;
  961. if(f != Z)
  962. naddr(f, &p->from);
  963. if(t != Z)
  964. naddr(t, &p->to);
  965. if(debug['g'])
  966. print("%P\n", p);
  967. }
  968. void
  969. gins3(int a, Node *f1, Node *f2, Node *t)
  970. {
  971. Adr ta;
  972. nextpc();
  973. p->as = a;
  974. if(f1 != Z)
  975. naddr(f1, &p->from);
  976. if(f2 != Z && (f2->op != OREGISTER || !samaddr(f2, t))) {
  977. ta = zprog.from; /* TO DO */
  978. naddr(f2, &ta);
  979. p->reg = ta.reg;
  980. if(ta.type == D_CONST && ta.offset == 0) {
  981. if(R0ISZERO)
  982. p->reg = REGZERO;
  983. else
  984. diag(Z, "REGZERO in gins3 %A", a);
  985. }else if(ta.type == D_CONST)
  986. p->from3 = ta;
  987. }
  988. if(t != Z)
  989. naddr(t, &p->to);
  990. if(debug['g'])
  991. print("%P\n", p);
  992. }
  993. void
  994. gins4(int a, Node *f1, Node *f2, Node *f3, Node *t)
  995. {
  996. Adr ta;
  997. nextpc();
  998. p->as = a;
  999. naddr(f1, &p->from);
  1000. if(f2->op != OREGISTER && (f2->op != OCONST || vconst(f2) != 0))
  1001. diag(f2, "invalid gins4");
  1002. naddr(f2, &ta);
  1003. p->reg = ta.reg;
  1004. if(ta.type == D_CONST && ta.offset == 0)
  1005. p->reg = REGZERO;
  1006. naddr(f3, &p->from3);
  1007. naddr(t, &p->to);
  1008. if(debug['g'])
  1009. print("%P\n", p);
  1010. }
  1011. void
  1012. gopcode(int o, Node *f1, Node *f2, Node *t)
  1013. {
  1014. int a, et, uns;
  1015. if(o == OAS) {
  1016. gmove(f1, t);
  1017. return;
  1018. }
  1019. et = TLONG;
  1020. if(f1 != Z && f1->type != T) {
  1021. if(f1->op == OCONST && t != Z && t->type != T)
  1022. et = t->type->etype;
  1023. else
  1024. et = f1->type->etype;
  1025. }
  1026. if((typev[et] || t->type != T && typev[t->type->etype]) && o != OFUNC) {
  1027. gopcode64(o, f1, f2, t);
  1028. return;
  1029. }
  1030. uns = 0;
  1031. a = AGOK;
  1032. switch(o) {
  1033. case OASADD:
  1034. case OADD:
  1035. a = AADD;
  1036. if(et == TFLOAT)
  1037. a = AFADDS;
  1038. else
  1039. if(et == TDOUBLE)
  1040. a = AFADD;
  1041. break;
  1042. case OASSUB:
  1043. case OSUB:
  1044. a = ASUB;
  1045. if(et == TFLOAT)
  1046. a = AFSUBS;
  1047. else
  1048. if(et == TDOUBLE)
  1049. a = AFSUB;
  1050. break;
  1051. case OASOR:
  1052. case OOR:
  1053. a = AOR;
  1054. break;
  1055. case OASAND:
  1056. case OAND:
  1057. a = AAND;
  1058. if(f1->op == OCONST)
  1059. a = AANDCC;
  1060. break;
  1061. case OASXOR:
  1062. case OXOR:
  1063. a = AXOR;
  1064. break;
  1065. case OASLSHR:
  1066. case OLSHR:
  1067. a = ASRW;
  1068. break;
  1069. case OASASHR:
  1070. case OASHR:
  1071. a = ASRAW;
  1072. break;
  1073. case OASASHL:
  1074. case OASHL:
  1075. a = ASLW;
  1076. break;
  1077. case OFUNC:
  1078. a = ABL;
  1079. break;
  1080. case OASLMUL:
  1081. case OLMUL:
  1082. case OASMUL:
  1083. case OMUL:
  1084. if(et == TFLOAT) {
  1085. a = AFMULS;
  1086. break;
  1087. } else
  1088. if(et == TDOUBLE) {
  1089. a = AFMUL;
  1090. break;
  1091. }
  1092. a = AMULLW;
  1093. break;
  1094. case OASDIV:
  1095. case ODIV:
  1096. if(et == TFLOAT) {
  1097. a = AFDIVS;
  1098. break;
  1099. } else
  1100. if(et == TDOUBLE) {
  1101. a = AFDIV;
  1102. break;
  1103. }
  1104. a = ADIVW;
  1105. break;
  1106. case OASMOD:
  1107. case OMOD:
  1108. a = AREM;
  1109. break;
  1110. case OASLMOD:
  1111. case OLMOD:
  1112. a = AREMU;
  1113. break;
  1114. case OASLDIV:
  1115. case OLDIV:
  1116. a = ADIVWU;
  1117. break;
  1118. case OCOM:
  1119. a = ANOR;
  1120. break;
  1121. case ONEG:
  1122. a = ANEG;
  1123. if(et == TFLOAT || et == TDOUBLE)
  1124. a = AFNEG;
  1125. break;
  1126. case OEQ:
  1127. a = ABEQ;
  1128. if(t->op == OCONST && t->vconst >= (1<<15))
  1129. goto cmpu;
  1130. goto cmp;
  1131. case ONE:
  1132. a = ABNE;
  1133. if(t->op == OCONST && t->vconst >= (1<<15))
  1134. goto cmpu;
  1135. goto cmp;
  1136. case OLT:
  1137. a = ABLT;
  1138. goto cmp;
  1139. case OLE:
  1140. a = ABLE;
  1141. goto cmp;
  1142. case OGE:
  1143. a = ABGE;
  1144. goto cmp;
  1145. case OGT:
  1146. a = ABGT;
  1147. goto cmp;
  1148. case OLO:
  1149. a = ABLT;
  1150. goto cmpu;
  1151. case OLS:
  1152. a = ABLE;
  1153. goto cmpu;
  1154. case OHS:
  1155. a = ABGE;
  1156. goto cmpu;
  1157. case OHI:
  1158. a = ABGT;
  1159. goto cmpu;
  1160. cmpu:
  1161. uns = 1;
  1162. cmp:
  1163. nextpc();
  1164. p->as = uns? ACMPU: ACMP;
  1165. if(et == TFLOAT)
  1166. p->as = AFCMPU;
  1167. else
  1168. if(et == TDOUBLE)
  1169. p->as = AFCMPU;
  1170. if(f1 != Z)
  1171. naddr(f1, &p->from);
  1172. if(t != Z)
  1173. naddr(t, &p->to);
  1174. if(f1 == Z || t == Z || f2 != Z)
  1175. diag(Z, "bad cmp in gopcode %O", o);
  1176. if(debug['g'])
  1177. print("%P\n", p);
  1178. f1 = Z;
  1179. f2 = Z;
  1180. t = Z;
  1181. break;
  1182. }
  1183. if(a == AGOK)
  1184. diag(Z, "bad in gopcode %O", o);
  1185. gins3(a, f1, f2, t);
  1186. }
  1187. static void
  1188. gopcode64(int o, Node *f1, Node *f2, Node *t)
  1189. {
  1190. int a1, a2;
  1191. Node nod, nod1, nod2, sh;
  1192. ulong m;
  1193. Prog *p1;
  1194. if(t->op != OREGPAIR || f2 != Z && f2->op != OREGPAIR) {
  1195. diag(Z, "bad f2/dest in gopcode64 %O", o);
  1196. return;
  1197. }
  1198. if(f1->op != OCONST &&
  1199. (typev[f1->type->etype] && f1->op != OREGPAIR || !typev[f1->type->etype] && f1->op != OREGISTER)) {
  1200. diag(Z, "bad f1[%O] in gopcode64 %O", f1->op, o);
  1201. return;
  1202. }
  1203. /* a1 for low-order, a2 for high-order */
  1204. a1 = AGOK;
  1205. a2 = AGOK;
  1206. switch(o) {
  1207. case OASADD:
  1208. case OADD:
  1209. if(f1->op == OCONST && sconst(f1)) {
  1210. if(f2 == Z)
  1211. f2 = t;
  1212. gins3(AADDC, f1, f2->right, t->right);
  1213. if((f1->vconst>>32) == 0)
  1214. gins(AADDZE, f2->left, t->left);
  1215. else if((f1->vconst>>32) == -1)
  1216. gins(AADDME, f2->left, t->left);
  1217. else
  1218. diag(t, "odd vlong ADD: %lld", f1->vconst);
  1219. return;
  1220. }
  1221. a1 = AADDC;
  1222. a2 = AADDE;
  1223. break;
  1224. case OASSUB:
  1225. case OSUB:
  1226. a1 = ASUBC;
  1227. a2 = ASUBE;
  1228. break;
  1229. case OASOR:
  1230. case OOR:
  1231. if(f1->op == OCONST) {
  1232. gori64(AOR, f1, f2, t);
  1233. return;
  1234. }
  1235. a1 = a2 = AOR;
  1236. break;
  1237. case OASAND:
  1238. case OAND:
  1239. if(f1->op == OCONST) {
  1240. gandi64(AANDCC, f1, f2, t);
  1241. return;
  1242. }
  1243. a1 = a2 = AAND;
  1244. break;
  1245. case OASXOR:
  1246. case OXOR:
  1247. if(f1->op == OCONST) {
  1248. gori64(AXOR, f1, f2, t);
  1249. return;
  1250. }
  1251. a1 = a2 = AXOR;
  1252. break;
  1253. case OASLSHR:
  1254. case OLSHR:
  1255. if(f2 == Z)
  1256. f2 = t;
  1257. if(f1->op == OCONST) {
  1258. if(f1->vconst >= 32) {
  1259. if(f1->vconst == 32)
  1260. gmove(f2->left, t->right);
  1261. else if(f1->vconst < 64)
  1262. gins3(ASRW, nodconst(f1->vconst-32), f2->left, t->right);
  1263. else
  1264. gmove(nodconst(0), t->right);
  1265. gmove(nodconst(0), t->left);
  1266. return;
  1267. }
  1268. if(f1->vconst <= 0) {
  1269. if(f2 != t)
  1270. gmove(f2, t);
  1271. return;
  1272. }
  1273. sh = *nodconst(32 - f1->vconst);
  1274. m = 0xFFFFFFFFUL >> f1->vconst;
  1275. gins4(ARLWNM, &sh, f2->right, nodconst(m), t->right);
  1276. gins4(ARLWMI, &sh, f2->left, nodconst(~m), t->right);
  1277. gins4(ARLWNM, &sh, f2->left, nodconst(m), t->left);
  1278. return;
  1279. }
  1280. regalloc(&nod, &regnode, Z);
  1281. gins3(ASUBC, f1, nodconst(32), &nod);
  1282. gins3(ASRW, f1, f2->right, t->right);
  1283. regalloc(&nod1, &regnode, Z);
  1284. gins3(ASLW, &nod, f2->left, &nod1);
  1285. gins(AOR, &nod1, t->right);
  1286. gins3(AADD, nodconst(-32), f1, &nod);
  1287. gins3(ASRW, &nod, f2->left, &nod1);
  1288. gins(AOR, &nod1, t->right);
  1289. gins3(ASRW, f1, f2->left, t->left);
  1290. regfree(&nod);
  1291. regfree(&nod1);
  1292. return;
  1293. case OASASHR:
  1294. case OASHR:
  1295. if(f2 == Z)
  1296. f2 = t;
  1297. if(f1->op == OCONST) {
  1298. if(f1->vconst >= 32) {
  1299. if(f1->vconst == 32)
  1300. gmove(f2->left, t->right);
  1301. else if(f1->vconst < 64)
  1302. gins3(ASRAW, nodconst(f1->vconst-32), f2->left, t->right);
  1303. gins3(ASRAW, nodconst(31), f2->left, t->left);
  1304. if(f1->vconst >= 64) {
  1305. gmove(t->left, t->right);
  1306. return;
  1307. }
  1308. return;
  1309. }
  1310. if(f1->vconst <= 0) {
  1311. if(f2 != t)
  1312. gmove(f2, t);
  1313. return;
  1314. }
  1315. sh = *nodconst(32 - f1->vconst);
  1316. m = 0xFFFFFFFFUL >> f1->vconst;
  1317. gins4(ARLWNM, &sh, f2->right, nodconst(m), t->right);
  1318. gins4(ARLWMI, &sh, f2->left, nodconst(~m), t->right);
  1319. gins3(ASRAW, &sh, f2->left, t->left);
  1320. return;
  1321. }
  1322. regalloc(&nod, &regnode, Z);
  1323. gins3(ASUBC, f1, nodconst(32), &nod);
  1324. gins3(ASRW, f1, f2->right, t->right);
  1325. regalloc(&nod1, &regnode, Z);
  1326. gins3(ASLW, &nod, f2->left, &nod1);
  1327. gins(AOR, &nod1, t->right);
  1328. gins3(AADDCCC, nodconst(-32), f1, &nod);
  1329. gins3(ASRAW, &nod, f2->left, &nod1);
  1330. gins(ABLE, Z, Z);
  1331. p1 = p;
  1332. gins(AMOVW, &nod1, t->right);
  1333. patch(p1, pc);
  1334. gins3(ASRAW, f1, f2->left, t->left);
  1335. regfree(&nod);
  1336. regfree(&nod1);
  1337. return;
  1338. case OASASHL:
  1339. case OASHL:
  1340. if(f2 == Z)
  1341. f2 = t;
  1342. if(f1->op == OCONST) {
  1343. if(f1->vconst >= 32) {
  1344. if(f1->vconst == 32)
  1345. gmove(f2->right, t->left);
  1346. else if(f1->vconst >= 64)
  1347. gmove(nodconst(0), t->left);
  1348. else
  1349. gins3(ASLW, nodconst(f1->vconst-32), f2->right, t->left);
  1350. gmove(nodconst(0), t->right);
  1351. return;
  1352. }
  1353. if(f1->vconst <= 0) {
  1354. if(f2 != t)
  1355. gmove(f2, t);
  1356. return;
  1357. }
  1358. m = 0xFFFFFFFFUL << f1->vconst;
  1359. gins4(ARLWNM, f1, f2->left, nodconst(m), t->left);
  1360. gins4(ARLWMI, f1, f2->right, nodconst(~m), t->left);
  1361. gins4(ARLWNM, f1, f2->right, nodconst(m), t->right);
  1362. return;
  1363. }
  1364. regalloc(&nod, &regnode, Z);
  1365. gins3(ASUBC, f1, nodconst(32), &nod);
  1366. gins3(ASLW, f1, f2->left, t->left);
  1367. regalloc(&nod1, &regnode, Z);
  1368. gins3(ASRW, &nod, f2->right, &nod1);
  1369. gins(AOR, &nod1, t->left);
  1370. gins3(AADD, nodconst(-32), f1, &nod);
  1371. gins3(ASLW, &nod, f2->right, &nod1);
  1372. gins(AOR, &nod1, t->left);
  1373. gins3(ASLW, f1, f2->right, t->right);
  1374. regfree(&nod);
  1375. regfree(&nod1);
  1376. return;
  1377. case OASLMUL:
  1378. case OLMUL:
  1379. case OASMUL:
  1380. case OMUL:
  1381. if(f2 == Z)
  1382. f2 = t;
  1383. regalloc(&nod, &regnode, Z);
  1384. gins3(AMULLW, f1->right, f2->right, &nod); /* lo(f2.low*f1.low) */
  1385. regalloc(&nod1, &regnode, Z);
  1386. gins3(AMULHWU, f1->right, f2->right, &nod1); /* hi(f2.low*f1.low) */
  1387. regalloc(&nod2, &regnode, Z);
  1388. gins3(AMULLW, f2->right, f1->left, &nod2); /* lo(f2.low*f1.high) */
  1389. gins(AADD, &nod2, &nod1);
  1390. gins3(AMULLW, f1->right, f2->left, &nod2); /* lo(f2.high*f1.low) */
  1391. gins(AADD, &nod2, &nod1);
  1392. regfree(&nod2);
  1393. gmove(&nod, t->right);
  1394. gmove(&nod1, t->left);
  1395. regfree(&nod);
  1396. regfree(&nod1);
  1397. return;
  1398. case OCOM:
  1399. a1 = a2 = ANOR;
  1400. break;
  1401. case ONEG:
  1402. gins3(ASUBC, t->right, nodconst(0), t->right);
  1403. gins(ASUBZE, t->left, t->left);
  1404. return;
  1405. }
  1406. if(a1 == AGOK || a2 == AGOK)
  1407. diag(Z, "bad in gopcode64 %O", o);
  1408. if(f1->op == OCONST) {
  1409. if(f2 != Z & f2 != t)
  1410. diag(Z, "bad const in gopcode64 %O", o);
  1411. gins(a1, nod32const(f1->vconst), t->right);
  1412. gins(a2, nod32const(f1->vconst>>32), t->left);
  1413. } else {
  1414. if(f2 != Z && f2 != t) {
  1415. gins3(a1, f1->right, f2->right, t->right);
  1416. gins3(a2, f1->left, f2->left, t->left);
  1417. } else {
  1418. gins(a1, f1->right, t->right);
  1419. gins(a2, f1->left, t->left);
  1420. }
  1421. }
  1422. }
  1423. samaddr(Node *f, Node *t)
  1424. {
  1425. if(f->op != t->op)
  1426. return 0;
  1427. switch(f->op) {
  1428. case OREGISTER:
  1429. if(f->reg != t->reg)
  1430. break;
  1431. return 1;
  1432. case OREGPAIR:
  1433. return samaddr(f->left, t->left) && samaddr(f->right, t->right);
  1434. }
  1435. return 0;
  1436. }
  1437. static void
  1438. gori64(int a, Node *f1, Node *f2, Node *t)
  1439. {
  1440. ulong lo, hi;
  1441. if(f2 == Z)
  1442. f2 = t;
  1443. lo = f1->vconst & MASK(32);
  1444. hi = (f1->vconst >> 32) & MASK(32);
  1445. if(lo & 0xFFFF)
  1446. gins3(a, nodconst(lo & 0xFFFF), f2->right, t->right);
  1447. if((lo >> 16) != 0)
  1448. gins3(a, nodconst(lo & 0xFFFF0000UL), f2->right, t->right);
  1449. if(hi & 0xFFFF)
  1450. gins3(a, nodconst(hi & 0xFFFF), f2->left, t->left);
  1451. if((hi >> 16) != 0)
  1452. gins3(a, nodconst(hi & 0xFFFF0000UL), f2->left, t->left);
  1453. }
  1454. static void
  1455. gandi64(int a, Node *f1, Node *f2, Node *t)
  1456. {
  1457. ulong lo, hi;
  1458. if(f2 == Z)
  1459. f2 = t;
  1460. lo = f1->vconst & MASK(32);
  1461. hi = (f1->vconst >> 32) & MASK(32);
  1462. if(lo == 0)
  1463. gins(AMOVW, nodconst(0), t->right);
  1464. else
  1465. gins3(a, nodconst(lo), f2->right, t->right);
  1466. if(hi == 0)
  1467. gins(AMOVW, nodconst(0), t->left);
  1468. else
  1469. gins3(a, nodconst(hi), f2->left, t->left);
  1470. }
  1471. void
  1472. gbranch(int o)
  1473. {
  1474. int a;
  1475. a = AGOK;
  1476. switch(o) {
  1477. case ORETURN:
  1478. a = ARETURN;
  1479. break;
  1480. case OGOTO:
  1481. a = ABR;
  1482. break;
  1483. }
  1484. nextpc();
  1485. if(a == AGOK) {
  1486. diag(Z, "bad in gbranch %O", o);
  1487. nextpc();
  1488. }
  1489. p->as = a;
  1490. }
  1491. void
  1492. patch(Prog *op, long pc)
  1493. {
  1494. op->to.offset = pc;
  1495. op->to.type = D_BRANCH;
  1496. }
  1497. void
  1498. gpseudo(int a, Sym *s, Node *n)
  1499. {
  1500. nextpc();
  1501. p->as = a;
  1502. p->from.type = D_OREG;
  1503. p->from.sym = s;
  1504. if(a == ATEXT)
  1505. p->reg = (profileflg ? 0 : NOPROF);
  1506. p->from.name = D_EXTERN;
  1507. if(s->class == CSTATIC)
  1508. p->from.name = D_STATIC;
  1509. naddr(n, &p->to);
  1510. if(a == ADATA || a == AGLOBL)
  1511. pc--;
  1512. }
  1513. int
  1514. sval(long v)
  1515. {
  1516. if(v >= -(1<<15) && v < (1<<15))
  1517. return 1;
  1518. return 0;
  1519. }
  1520. int
  1521. sconst(Node *n)
  1522. {
  1523. vlong vv;
  1524. if(n->op == OCONST) {
  1525. if(!typefd[n->type->etype]) {
  1526. vv = n->vconst;
  1527. if(vv >= -(((vlong)1)<<15) && vv < (((vlong)1)<<15))
  1528. return 1;
  1529. }
  1530. }
  1531. return 0;
  1532. }
  1533. int
  1534. uconst(Node *n)
  1535. {
  1536. vlong vv;
  1537. if(n->op == OCONST) {
  1538. if(!typefd[n->type->etype]) {
  1539. vv = n->vconst;
  1540. if(vv >= 0 && vv < (((vlong)1)<<16))
  1541. return 1;
  1542. }
  1543. }
  1544. return 0;
  1545. }
  1546. long
  1547. exreg(Type *t)
  1548. {
  1549. long o;
  1550. if(typechlp[t->etype]) {
  1551. if(exregoffset <= 3)
  1552. return 0;
  1553. o = exregoffset;
  1554. exregoffset--;
  1555. return o;
  1556. }
  1557. if(typefd[t->etype]) {
  1558. if(exfregoffset <= 16)
  1559. return 0;
  1560. o = exfregoffset + NREG;
  1561. exfregoffset--;
  1562. return o;
  1563. }
  1564. return 0;
  1565. }
  1566. schar ewidth[NTYPE] =
  1567. {
  1568. -1, /* [TXXX] */
  1569. SZ_CHAR, /* [TCHAR] */
  1570. SZ_CHAR, /* [TUCHAR] */
  1571. SZ_SHORT, /* [TSHORT] */
  1572. SZ_SHORT, /* [TUSHORT] */
  1573. SZ_INT, /* [TINT] */
  1574. SZ_INT, /* [TUINT] */
  1575. SZ_LONG, /* [TLONG] */
  1576. SZ_LONG, /* [TULONG] */
  1577. SZ_VLONG, /* [TVLONG] */
  1578. SZ_VLONG, /* [TUVLONG] */
  1579. SZ_FLOAT, /* [TFLOAT] */
  1580. SZ_DOUBLE, /* [TDOUBLE] */
  1581. SZ_IND, /* [TIND] */
  1582. 0, /* [TFUNC] */
  1583. -1, /* [TARRAY] */
  1584. 0, /* [TVOID] */
  1585. -1, /* [TSTRUCT] */
  1586. -1, /* [TUNION] */
  1587. SZ_INT, /* [TENUM] */
  1588. };
  1589. long ncast[NTYPE] =
  1590. {
  1591. 0, /* [TXXX] */
  1592. BCHAR|BUCHAR, /* [TCHAR] */
  1593. BCHAR|BUCHAR, /* [TUCHAR] */
  1594. BSHORT|BUSHORT, /* [TSHORT] */
  1595. BSHORT|BUSHORT, /* [TUSHORT] */
  1596. BINT|BUINT|BLONG|BULONG|BIND, /* [TINT] */
  1597. BINT|BUINT|BLONG|BULONG|BIND, /* [TUINT] */
  1598. BINT|BUINT|BLONG|BULONG|BIND, /* [TLONG] */
  1599. BINT|BUINT|BLONG|BULONG|BIND, /* [TULONG] */
  1600. BVLONG|BUVLONG, /* [TVLONG] */
  1601. BVLONG|BUVLONG, /* [TUVLONG] */
  1602. BFLOAT, /* [TFLOAT] */
  1603. BDOUBLE, /* [TDOUBLE] */
  1604. BLONG|BULONG|BIND, /* [TIND] */
  1605. 0, /* [TFUNC] */
  1606. 0, /* [TARRAY] */
  1607. 0, /* [TVOID] */
  1608. BSTRUCT, /* [TSTRUCT] */
  1609. BUNION, /* [TUNION] */
  1610. 0, /* [TENUM] */
  1611. };