swt.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
  1. #include "gc.h"
  2. int
  3. swcmp(void *a1, void *a2)
  4. {
  5. C1 *p1, *p2;
  6. p1 = a1;
  7. p2 = a2;
  8. if(p1->val < p2->val)
  9. return -1;
  10. return p1->val > p2->val;
  11. }
  12. void
  13. doswit(Node *n)
  14. {
  15. Case *c;
  16. C1 *q, *iq;
  17. long def, nc, i;
  18. Node tn;
  19. def = 0;
  20. nc = 0;
  21. for(c = cases; c->link != C; c = c->link) {
  22. if(c->def) {
  23. if(def)
  24. diag(n, "more than one default in switch");
  25. def = c->label;
  26. continue;
  27. }
  28. nc++;
  29. }
  30. i = nc*sizeof(C1);
  31. while(nhunk < i)
  32. gethunk();
  33. iq = (C1*)hunk;
  34. nhunk -= i;
  35. hunk += i;
  36. q = iq;
  37. for(c = cases; c->link != C; c = c->link) {
  38. if(c->def)
  39. continue;
  40. q->label = c->label;
  41. q->val = c->val;
  42. q++;
  43. }
  44. qsort(iq, nc, sizeof(C1), swcmp);
  45. if(debug['W'])
  46. for(i=0; i<nc; i++)
  47. print("case %2ld: = %.8lux\n", i, iq[i].val);
  48. if(def == 0)
  49. def = breakpc;
  50. for(i=0; i<nc-1; i++)
  51. if(iq[i].val == iq[i+1].val)
  52. diag(n, "duplicate cases in switch %ld", iq[i].val);
  53. regalloc(&tn, &regnode, Z);
  54. swit1(iq, nc, def, n, &tn);
  55. regfree(&tn);
  56. }
  57. void
  58. swit1(C1 *q, int nc, long def, Node *n, Node *tn)
  59. {
  60. C1 *r;
  61. int i;
  62. Prog *sp;
  63. if(nc < 5) {
  64. for(i=0; i<nc; i++) {
  65. if(debug['W'])
  66. print("case = %.8lux\n", q->val);
  67. if(bval(q->val)) {
  68. gopcode(OEQ, n, Z, nodconst(q->val));
  69. } else {
  70. gopcode(OSUB, nodconst(q->val), n, tn);
  71. gopcode(OEQ, tn, Z, nodconst(0));
  72. }
  73. patch(p, q->label);
  74. q++;
  75. }
  76. gbranch(OGOTO);
  77. patch(p, def);
  78. return;
  79. }
  80. i = nc / 2;
  81. r = q+i;
  82. if(bval(r->val)) {
  83. gopcode(OGE, n, Z, nodconst(r->val));
  84. sp = p;
  85. swit1(q, i, def, n, tn);
  86. patch(sp, pc);
  87. swit1(r, nc-i, def, n, tn);
  88. } else {
  89. gopcode(OSUB, nodconst(r->val), n, tn);
  90. gopcode(OGE, tn, Z, nodconst(0));
  91. sp = p;
  92. swit1(q, i, def, n, tn);
  93. patch(sp, pc);
  94. swit1(r, nc-i, def, n, tn);
  95. }
  96. /* if(debug['W'])
  97. print("case > %.8lux\n", r->val);
  98. gmove(nodconst(r->val), tn);
  99. gopcode(OLT, tn, n, Z);
  100. sp = p;
  101. gopcode(OEQ, n, tn, Z);
  102. patch(p, r->label);
  103. swit1(q, i, def, n, tn);
  104. if(debug['W'])
  105. print("case < %.8lux\n", r->val);
  106. patch(sp, pc);
  107. swit1(r+1, nc-i-1, def, n, tn); */
  108. }
  109. void
  110. cas(void)
  111. {
  112. Case *c;
  113. c = alloc(sizeof(*c));
  114. c->link = cases;
  115. cases = c;
  116. }
  117. void
  118. bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
  119. {
  120. int sh;
  121. long v;
  122. Node *l;
  123. /*
  124. * n1 gets adjusted/masked value
  125. * n2 gets address of cell
  126. * n3 gets contents of cell
  127. */
  128. l = b->left;
  129. if(n2 != Z) {
  130. regalloc(n1, l, nn);
  131. reglcgen(n2, l, Z);
  132. regalloc(n3, l, Z);
  133. gopcode(OAS, n2, Z, n3);
  134. gopcode(OAS, n3, Z, n1);
  135. } else {
  136. regalloc(n1, l, nn);
  137. cgen(l, n1);
  138. }
  139. if(b->type->shift == 0 && typeu[b->type->etype]) {
  140. v = ~0 + (1L << b->type->nbits);
  141. gopcode(OAND, nodconst(v), Z, n1);
  142. } else {
  143. sh = 32 - b->type->shift - b->type->nbits;
  144. if(sh > 0)
  145. gopcode(OASHL, nodconst(sh), Z, n1);
  146. sh += b->type->shift;
  147. if(sh > 0)
  148. if(typeu[b->type->etype])
  149. gopcode(OLSHR, nodconst(sh), Z, n1);
  150. else
  151. gopcode(OASHR, nodconst(sh), Z, n1);
  152. }
  153. }
  154. void
  155. bitstore(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
  156. {
  157. long v;
  158. Node nod, *l;
  159. int sh;
  160. /*
  161. * n1 has adjusted/masked value
  162. * n2 has address of cell
  163. * n3 has contents of cell
  164. */
  165. l = b->left;
  166. regalloc(&nod, l, Z);
  167. v = ~0 + (1L << b->type->nbits);
  168. gopcode(OAND, nodconst(v), Z, n1);
  169. gopcode(OAS, n1, Z, &nod);
  170. if(nn != Z)
  171. gopcode(OAS, n1, Z, nn);
  172. sh = b->type->shift;
  173. if(sh > 0)
  174. gopcode(OASHL, nodconst(sh), Z, &nod);
  175. v <<= sh;
  176. gopcode(OAND, nodconst(~v), Z, n3);
  177. gopcode(OOR, n3, Z, &nod);
  178. gopcode(OAS, &nod, Z, n2);
  179. regfree(&nod);
  180. regfree(n1);
  181. regfree(n2);
  182. regfree(n3);
  183. }
  184. long
  185. outstring(char *s, long n)
  186. {
  187. long r;
  188. r = nstring;
  189. while(n) {
  190. string[mnstring] = *s++;
  191. mnstring++;
  192. nstring++;
  193. if(mnstring >= NSNAME) {
  194. gpseudo(ADATA, symstring, nodconst(0L));
  195. p->from.offset += nstring - NSNAME;
  196. p->reg = NSNAME;
  197. p->to.type = D_SCONST;
  198. memmove(p->to.sval, string, NSNAME);
  199. mnstring = 0;
  200. }
  201. n--;
  202. }
  203. return r;
  204. }
  205. long
  206. outlstring(ushort *s, long n)
  207. {
  208. char buf[2];
  209. int c;
  210. long r;
  211. while(nstring & 1)
  212. outstring("", 1);
  213. r = nstring;
  214. while(n > 0) {
  215. c = *s++;
  216. if(align(0, types[TCHAR], Aarg1)) {
  217. buf[0] = c>>8;
  218. buf[1] = c;
  219. } else {
  220. buf[0] = c;
  221. buf[1] = c>>8;
  222. }
  223. outstring(buf, 2);
  224. n -= sizeof(ushort);
  225. }
  226. return r;
  227. }
  228. int
  229. mulcon(Node *n, Node *nn)
  230. {
  231. Node *l, *r, nod1, nod2;
  232. Multab *m;
  233. long v;
  234. int o;
  235. char code[sizeof(m->code)+2], *p;
  236. if(typefd[n->type->etype])
  237. return 0;
  238. l = n->left;
  239. r = n->right;
  240. if(l->op == OCONST) {
  241. l = r;
  242. r = n->left;
  243. }
  244. if(r->op != OCONST)
  245. return 0;
  246. v = convvtox(r->vconst, n->type->etype);
  247. if(v != r->vconst) {
  248. if(debug['M'])
  249. print("%L multiply conv: %lld\n", n->lineno, r->vconst);
  250. return 0;
  251. }
  252. m = mulcon0(v);
  253. if(!m) {
  254. if(debug['M'])
  255. print("%L multiply table: %lld\n", n->lineno, r->vconst);
  256. return 0;
  257. }
  258. if(debug['M'] && debug['v'])
  259. print("%L multiply: %ld\n", n->lineno, v);
  260. memmove(code, m->code, sizeof(m->code));
  261. code[sizeof(m->code)] = 0;
  262. p = code;
  263. if(p[1] == 'i')
  264. p += 2;
  265. regalloc(&nod1, n, nn);
  266. cgen(l, &nod1);
  267. if(v < 0)
  268. gopcode(OSUB, &nod1, nodconst(0), &nod1);
  269. regalloc(&nod2, n, Z);
  270. loop:
  271. switch(*p) {
  272. case 0:
  273. regfree(&nod2);
  274. gopcode(OAS, &nod1, Z, nn);
  275. regfree(&nod1);
  276. return 1;
  277. case '+':
  278. o = OADD;
  279. goto addsub;
  280. case '-':
  281. o = OSUB;
  282. addsub: /* number is r,n,l */
  283. v = p[1] - '0';
  284. r = &nod1;
  285. if(v&4)
  286. r = &nod2;
  287. n = &nod1;
  288. if(v&2)
  289. n = &nod2;
  290. l = &nod1;
  291. if(v&1)
  292. l = &nod2;
  293. gopcode(o, l, n, r);
  294. break;
  295. default: /* op is shiftcount, number is r,l */
  296. v = p[1] - '0';
  297. r = &nod1;
  298. if(v&2)
  299. r = &nod2;
  300. l = &nod1;
  301. if(v&1)
  302. l = &nod2;
  303. v = *p - 'a';
  304. if(v < 0 || v >= 32) {
  305. diag(n, "mulcon unknown op: %c%c", p[0], p[1]);
  306. break;
  307. }
  308. gopcode(OASHL, nodconst(v), l, r);
  309. break;
  310. }
  311. p += 2;
  312. goto loop;
  313. }
  314. void
  315. nullwarn(Node *l, Node *r)
  316. {
  317. warn(Z, "result of operation not used");
  318. if(l != Z)
  319. cgen(l, Z);
  320. if(r != Z)
  321. cgen(r, Z);
  322. }
  323. void
  324. sextern(Sym *s, Node *a, long o, long w)
  325. {
  326. long e, lw;
  327. for(e=0; e<w; e+=NSNAME) {
  328. lw = NSNAME;
  329. if(w-e < lw)
  330. lw = w-e;
  331. gpseudo(ADATA, s, nodconst(0));
  332. p->from.offset += o+e;
  333. p->reg = lw;
  334. p->to.type = D_SCONST;
  335. memmove(p->to.sval, a->cstring+e, lw);
  336. }
  337. }
  338. void
  339. gextern(Sym *s, Node *a, long o, long w)
  340. {
  341. gpseudo(ADATA, s, a);
  342. p->from.offset += o;
  343. p->reg = w;
  344. if(p->to.type == D_OREG)
  345. p->to.type = D_CONST;
  346. }
  347. void zname(Biobuf*, char*, int, int);
  348. char* zaddr(char*, Adr*, int);
  349. void zwrite(Biobuf*, Prog*, int, int);
  350. void outhist(Biobuf*);
  351. void
  352. zwrite(Biobuf *b, Prog *p, int sf, int st)
  353. {
  354. char bf[100], *bp;
  355. bf[0] = p->as;
  356. bf[1] = p->reg;
  357. bf[2] = p->lineno;
  358. bf[3] = p->lineno>>8;
  359. bf[4] = p->lineno>>16;
  360. bf[5] = p->lineno>>24;
  361. bp = zaddr(bf+6, &p->from, sf);
  362. bp = zaddr(bp, &p->to, st);
  363. Bwrite(b, bf, bp-bf);
  364. }
  365. void
  366. outcode(void)
  367. {
  368. struct { Sym *sym; short type; } h[NSYM];
  369. Prog *p;
  370. Sym *s;
  371. int sf, st, t, sym;
  372. if(debug['S']) {
  373. for(p = firstp; p != P; p = p->link)
  374. if(p->as != ADATA && p->as != AGLOBL)
  375. pc--;
  376. for(p = firstp; p != P; p = p->link) {
  377. print("%P\n", p);
  378. if(p->as != ADATA && p->as != AGLOBL)
  379. pc++;
  380. }
  381. }
  382. outhist(&outbuf);
  383. for(sym=0; sym<NSYM; sym++) {
  384. h[sym].sym = S;
  385. h[sym].type = 0;
  386. }
  387. sym = 1;
  388. for(p = firstp; p != P; p = p->link) {
  389. jackpot:
  390. sf = 0;
  391. s = p->from.sym;
  392. while(s != S) {
  393. sf = s->sym;
  394. if(sf < 0 || sf >= NSYM)
  395. sf = 0;
  396. t = p->from.name;
  397. if(h[sf].type == t)
  398. if(h[sf].sym == s)
  399. break;
  400. zname(&outbuf, s->name, t, sym);
  401. s->sym = sym;
  402. h[sym].sym = s;
  403. h[sym].type = t;
  404. sf = sym;
  405. sym++;
  406. if(sym >= NSYM)
  407. sym = 1;
  408. break;
  409. }
  410. st = 0;
  411. s = p->to.sym;
  412. while(s != S) {
  413. st = s->sym;
  414. if(st < 0 || st >= NSYM)
  415. st = 0;
  416. t = p->to.name;
  417. if(h[st].type == t)
  418. if(h[st].sym == s)
  419. break;
  420. zname(&outbuf, s->name, t, sym);
  421. s->sym = sym;
  422. h[sym].sym = s;
  423. h[sym].type = t;
  424. st = sym;
  425. sym++;
  426. if(sym >= NSYM)
  427. sym = 1;
  428. if(st == sf)
  429. goto jackpot;
  430. break;
  431. }
  432. zwrite(&outbuf, p, sf, st);
  433. }
  434. firstp = P;
  435. lastp = P;
  436. }
  437. void
  438. outhist(Biobuf *b)
  439. {
  440. Hist *h;
  441. char *p, *q, *op;
  442. Prog pg;
  443. int n;
  444. pg = zprog;
  445. pg.as = AHISTORY;
  446. for(h = hist; h != H; h = h->link) {
  447. p = h->name;
  448. op = 0;
  449. if(p && p[0] != '/' && h->offset == 0 && pathname && pathname[0] == '/') {
  450. op = p;
  451. p = pathname;
  452. }
  453. while(p) {
  454. q = utfrune(p, '/');
  455. if(q) {
  456. n = q-p;
  457. if(n == 0)
  458. n = 1; /* leading "/" */
  459. q++;
  460. } else {
  461. n = strlen(p);
  462. q = 0;
  463. }
  464. if(n) {
  465. Bputc(b, ANAME);
  466. Bputc(b, D_FILE);
  467. Bputc(b, 1);
  468. Bputc(b, '<');
  469. Bwrite(b, p, n);
  470. Bputc(b, 0);
  471. }
  472. p = q;
  473. if(p == 0 && op) {
  474. p = op;
  475. op = 0;
  476. }
  477. }
  478. pg.lineno = h->line;
  479. pg.to.type = zprog.to.type;
  480. pg.to.offset = h->offset;
  481. if(h->offset)
  482. pg.to.type = D_CONST;
  483. zwrite(b, &pg, 0, 0);
  484. }
  485. }
  486. void
  487. zname(Biobuf *b, char *n, int t, int s)
  488. {
  489. char bf[3];
  490. bf[0] = ANAME;
  491. bf[1] = t; /* type */
  492. bf[2] = s; /* sym */
  493. Bwrite(b, bf, 3);
  494. Bwrite(b, n, strlen(n)+1);
  495. }
  496. char*
  497. zaddr(char *bp, Adr *a, int s)
  498. {
  499. long l;
  500. vlong v;
  501. Ieee e;
  502. bp[0] = a->type;
  503. bp[1] = a->reg;
  504. bp[2] = s;
  505. bp[3] = a->name;
  506. bp += 4;
  507. switch(a->type) {
  508. default:
  509. diag(Z, "unknown type %d in zaddr", a->type);
  510. case D_NONE:
  511. case D_REG:
  512. case D_FREG:
  513. case D_FCREG:
  514. break;
  515. case D_OREG:
  516. case D_CONST:
  517. case D_BRANCH:
  518. v = a->offset;
  519. bp[0] = v;
  520. bp[1] = v>>8;
  521. bp[2] = v>>16;
  522. bp[3] = v>>24;
  523. bp[4] = v>>32;
  524. bp[5] = v>>40;
  525. bp[6] = v>>48;
  526. bp[7] = v>>56;
  527. bp += 8;
  528. break;
  529. case D_SCONST:
  530. memmove(bp, a->sval, NSNAME);
  531. bp += NSNAME;
  532. break;
  533. case D_FCONST:
  534. ieeedtod(&e, a->dval);
  535. l = e.l;
  536. bp[0] = l;
  537. bp[1] = l>>8;
  538. bp[2] = l>>16;
  539. bp[3] = l>>24;
  540. bp += 4;
  541. l = e.h;
  542. bp[0] = l;
  543. bp[1] = l>>8;
  544. bp[2] = l>>16;
  545. bp[3] = l>>24;
  546. bp += 4;
  547. break;
  548. }
  549. return bp;
  550. }
  551. void
  552. ieeedtod(Ieee *ieee, double native)
  553. {
  554. double fr, ho, f;
  555. int exp;
  556. if(native < 0) {
  557. ieeedtod(ieee, -native);
  558. ieee->h |= 0x80000000L;
  559. return;
  560. }
  561. if(native == 0) {
  562. ieee->l = 0;
  563. ieee->h = 0;
  564. return;
  565. }
  566. fr = frexp(native, &exp);
  567. f = 2097152L; /* shouldnt use fp constants here */
  568. fr = modf(fr*f, &ho);
  569. ieee->h = ho;
  570. ieee->h &= 0xfffffL;
  571. ieee->h |= (exp+1022L) << 20;
  572. f = 65536L;
  573. fr = modf(fr*f, &ho);
  574. ieee->l = ho;
  575. ieee->l <<= 16;
  576. ieee->l |= (long)(fr*f);
  577. }
  578. long
  579. align(long i, Type *t, int op)
  580. {
  581. long o;
  582. Type *v;
  583. int w;
  584. o = i;
  585. w = 1;
  586. switch(op) {
  587. default:
  588. diag(Z, "unknown align opcode %d", op);
  589. break;
  590. case Asu2: /* padding at end of a struct */
  591. w = SZ_VLONG;
  592. if(packflg)
  593. w = packflg;
  594. break;
  595. case Ael1: /* initial allign of struct element */
  596. for(v=t; v->etype==TARRAY; v=v->link)
  597. ;
  598. w = ewidth[v->etype];
  599. if(w <= 0 || w >= SZ_VLONG)
  600. w = SZ_VLONG;
  601. if(packflg)
  602. w = packflg;
  603. break;
  604. case Ael2: /* width of a struct element */
  605. o += t->width;
  606. break;
  607. case Aarg0: /* initial passbyptr argument in arg list */
  608. if(typesu[t->etype]) {
  609. o = align(o, types[TIND], Aarg1);
  610. o = align(o, types[TIND], Aarg2);
  611. }
  612. break;
  613. case Aarg1: /* initial allign of parameter */
  614. w = ewidth[t->etype];
  615. if(w <= 0 || w >= SZ_VLONG) {
  616. w = SZ_VLONG;
  617. break;
  618. }
  619. w = 1; /* little endian no adjustment */
  620. break;
  621. case Aarg2: /* width of a parameter */
  622. o += t->width;
  623. w = SZ_LONG;
  624. break;
  625. case Aaut3: /* total allign of automatic */
  626. o = align(o, t, Ael1);
  627. o = align(o, t, Ael2);
  628. break;
  629. }
  630. o = round(o, w);
  631. if(debug['A'])
  632. print("align %s %ld %T = %ld\n", bnames[op], i, t, o);
  633. return o;
  634. }
  635. long
  636. maxround(long max, long v)
  637. {
  638. v += SZ_VLONG-1;
  639. if(v > max)
  640. max = round(v, SZ_VLONG);
  641. return max;
  642. }