util.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653
  1. #include "all.h"
  2. #include <stdarg.h>
  3. typedef struct Bitset Bitset;
  4. typedef struct Vec Vec;
  5. typedef struct Bucket Bucket;
  6. struct Vec {
  7. ulong mag;
  8. Pool pool;
  9. size_t esz;
  10. ulong cap;
  11. union {
  12. long long ll;
  13. long double ld;
  14. void *ptr;
  15. } align[];
  16. };
  17. struct Bucket {
  18. uint nstr;
  19. char **str;
  20. };
  21. enum {
  22. VMin = 2,
  23. VMag = 0xcabba9e,
  24. NPtr = 256,
  25. IBits = 12,
  26. IMask = (1<<IBits) - 1,
  27. };
  28. Typ *typ;
  29. Ins insb[NIns], *curi;
  30. static void *ptr[NPtr];
  31. static void **pool = ptr;
  32. static int nptr = 1;
  33. static Bucket itbl[IMask+1]; /* string interning table */
  34. uint32_t
  35. hash(char *s)
  36. {
  37. uint32_t h;
  38. for (h=0; *s; ++s)
  39. h = *s + 17*h;
  40. return h;
  41. }
  42. void
  43. die_(char *file, char *s, ...)
  44. {
  45. va_list ap;
  46. fprintf(stderr, "%s: dying: ", file);
  47. va_start(ap, s);
  48. vfprintf(stderr, s, ap);
  49. va_end(ap);
  50. fputc('\n', stderr);
  51. abort();
  52. }
  53. void *
  54. emalloc(size_t n)
  55. {
  56. void *p;
  57. p = calloc(1, n);
  58. if (!p)
  59. die("emalloc, out of memory");
  60. return p;
  61. }
  62. void *
  63. alloc(size_t n)
  64. {
  65. void **pp;
  66. if (n == 0)
  67. return 0;
  68. if (nptr >= NPtr) {
  69. pp = emalloc(NPtr * sizeof(void *));
  70. pp[0] = pool;
  71. pool = pp;
  72. nptr = 1;
  73. }
  74. return pool[nptr++] = emalloc(n);
  75. }
  76. void
  77. freeall()
  78. {
  79. void **pp;
  80. for (;;) {
  81. for (pp = &pool[1]; pp < &pool[nptr]; pp++)
  82. free(*pp);
  83. pp = pool[0];
  84. if (!pp)
  85. break;
  86. free(pool);
  87. pool = pp;
  88. nptr = NPtr;
  89. }
  90. nptr = 1;
  91. }
  92. void *
  93. vnew(ulong len, size_t esz, Pool pool)
  94. {
  95. void *(*f)(size_t);
  96. ulong cap;
  97. Vec *v;
  98. for (cap=VMin; cap<len; cap*=2)
  99. ;
  100. f = pool == PHeap ? emalloc : alloc;
  101. v = f(cap * esz + sizeof(Vec));
  102. v->mag = VMag;
  103. v->cap = cap;
  104. v->esz = esz;
  105. v->pool = pool;
  106. return v + 1;
  107. }
  108. void
  109. vfree(void *p)
  110. {
  111. Vec *v;
  112. v = (Vec *)p - 1;
  113. assert(v->mag == VMag);
  114. if (v->pool == PHeap) {
  115. v->mag = 0;
  116. free(v);
  117. }
  118. }
  119. void
  120. vgrow(void *vp, ulong len)
  121. {
  122. Vec *v;
  123. void *v1;
  124. v = *(Vec **)vp - 1;
  125. assert(v+1 && v->mag == VMag);
  126. if (v->cap >= len)
  127. return;
  128. v1 = vnew(len, v->esz, v->pool);
  129. memcpy(v1, v+1, v->cap * v->esz);
  130. vfree(v+1);
  131. *(Vec **)vp = v1;
  132. }
  133. void
  134. strf(char str[NString], char *s, ...)
  135. {
  136. va_list ap;
  137. va_start(ap, s);
  138. vsnprintf(str, NString, s, ap);
  139. va_end(ap);
  140. }
  141. uint32_t
  142. intern(char *s)
  143. {
  144. Bucket *b;
  145. uint32_t h;
  146. uint i, n;
  147. h = hash(s) & IMask;
  148. b = &itbl[h];
  149. n = b->nstr;
  150. for (i=0; i<n; i++)
  151. if (strcmp(s, b->str[i]) == 0)
  152. return h + (i<<IBits);
  153. if (n == 1<<(32-IBits))
  154. die("interning table overflow");
  155. if (n == 0)
  156. b->str = vnew(1, sizeof b->str[0], PHeap);
  157. else if ((n & (n-1)) == 0)
  158. vgrow(&b->str, n+n);
  159. b->str[n] = emalloc(strlen(s)+1);
  160. b->nstr = n + 1;
  161. strcpy(b->str[n], s);
  162. return h + (n<<IBits);
  163. }
  164. char *
  165. str(uint32_t id)
  166. {
  167. assert(id>>IBits < itbl[id&IMask].nstr);
  168. return itbl[id&IMask].str[id>>IBits];
  169. }
  170. int
  171. isreg(Ref r)
  172. {
  173. return rtype(r) == RTmp && r.val < Tmp0;
  174. }
  175. int
  176. iscmp(int op, int *pk, int *pc)
  177. {
  178. if (Ocmpw <= op && op <= Ocmpw1) {
  179. *pc = op - Ocmpw;
  180. *pk = Kw;
  181. }
  182. else if (Ocmpl <= op && op <= Ocmpl1) {
  183. *pc = op - Ocmpl;
  184. *pk = Kl;
  185. }
  186. else if (Ocmps <= op && op <= Ocmps1) {
  187. *pc = NCmpI + op - Ocmps;
  188. *pk = Ks;
  189. }
  190. else if (Ocmpd <= op && op <= Ocmpd1) {
  191. *pc = NCmpI + op - Ocmpd;
  192. *pk = Kd;
  193. }
  194. else
  195. return 0;
  196. return 1;
  197. }
  198. int
  199. argcls(Ins *i, int n)
  200. {
  201. return optab[i->op].argcls[n][i->cls];
  202. }
  203. void
  204. emit(int op, int k, Ref to, Ref arg0, Ref arg1)
  205. {
  206. if (curi == insb)
  207. die("emit, too many instructions");
  208. *--curi = (Ins){
  209. .op = op, .cls = k,
  210. .to = to, .arg = {arg0, arg1}
  211. };
  212. }
  213. void
  214. emiti(Ins i)
  215. {
  216. emit(i.op, i.cls, i.to, i.arg[0], i.arg[1]);
  217. }
  218. void
  219. idup(Ins **pd, Ins *s, ulong n)
  220. {
  221. *pd = alloc(n * sizeof(Ins));
  222. if (n)
  223. memcpy(*pd, s, n * sizeof(Ins));
  224. }
  225. Ins *
  226. icpy(Ins *d, Ins *s, ulong n)
  227. {
  228. if (n)
  229. memcpy(d, s, n * sizeof(Ins));
  230. return d + n;
  231. }
  232. static int cmptab[][2] ={
  233. /* negation swap */
  234. [Ciule] = {Ciugt, Ciuge},
  235. [Ciult] = {Ciuge, Ciugt},
  236. [Ciugt] = {Ciule, Ciult},
  237. [Ciuge] = {Ciult, Ciule},
  238. [Cisle] = {Cisgt, Cisge},
  239. [Cislt] = {Cisge, Cisgt},
  240. [Cisgt] = {Cisle, Cislt},
  241. [Cisge] = {Cislt, Cisle},
  242. [Cieq] = {Cine, Cieq},
  243. [Cine] = {Cieq, Cine},
  244. [NCmpI+Cfle] = {NCmpI+Cfgt, NCmpI+Cfge},
  245. [NCmpI+Cflt] = {NCmpI+Cfge, NCmpI+Cfgt},
  246. [NCmpI+Cfgt] = {NCmpI+Cfle, NCmpI+Cflt},
  247. [NCmpI+Cfge] = {NCmpI+Cflt, NCmpI+Cfle},
  248. [NCmpI+Cfeq] = {NCmpI+Cfne, NCmpI+Cfeq},
  249. [NCmpI+Cfne] = {NCmpI+Cfeq, NCmpI+Cfne},
  250. [NCmpI+Cfo] = {NCmpI+Cfuo, NCmpI+Cfo},
  251. [NCmpI+Cfuo] = {NCmpI+Cfo, NCmpI+Cfuo},
  252. };
  253. int
  254. cmpneg(int c)
  255. {
  256. assert(0 <= c && c < NCmp);
  257. return cmptab[c][0];
  258. }
  259. int
  260. cmpop(int c)
  261. {
  262. assert(0 <= c && c < NCmp);
  263. return cmptab[c][1];
  264. }
  265. int
  266. clsmerge(short *pk, short k)
  267. {
  268. short k1;
  269. k1 = *pk;
  270. if (k1 == Kx) {
  271. *pk = k;
  272. return 0;
  273. }
  274. if ((k1 == Kw && k == Kl) || (k1 == Kl && k == Kw)) {
  275. *pk = Kw;
  276. return 0;
  277. }
  278. return k1 != k;
  279. }
  280. int
  281. phicls(int t, Tmp *tmp)
  282. {
  283. int t1;
  284. t1 = tmp[t].phi;
  285. if (!t1)
  286. return t;
  287. t1 = phicls(t1, tmp);
  288. tmp[t].phi = t1;
  289. return t1;
  290. }
  291. Ref
  292. newtmp(char *prfx, int k, Fn *fn)
  293. {
  294. static int n;
  295. int t;
  296. t = fn->ntmp++;
  297. vgrow(&fn->tmp, fn->ntmp);
  298. memset(&fn->tmp[t], 0, sizeof(Tmp));
  299. if (prfx)
  300. strf(fn->tmp[t].name, "%s.%d", prfx, ++n);
  301. fn->tmp[t].cls = k;
  302. fn->tmp[t].slot = -1;
  303. fn->tmp[t].nuse = +1;
  304. fn->tmp[t].ndef = +1;
  305. return TMP(t);
  306. }
  307. void
  308. chuse(Ref r, int du, Fn *fn)
  309. {
  310. if (rtype(r) == RTmp)
  311. fn->tmp[r.val].nuse += du;
  312. }
  313. int
  314. symeq(Sym s0, Sym s1)
  315. {
  316. return s0.type == s1.type && s0.id == s1.id;
  317. }
  318. Ref
  319. newcon(Con *c0, Fn *fn)
  320. {
  321. Con *c1;
  322. int i;
  323. for (i=1; i<fn->ncon; i++) {
  324. c1 = &fn->con[i];
  325. if (c0->type == c1->type
  326. && symeq(c0->sym, c1->sym)
  327. && c0->bits.i == c1->bits.i)
  328. return CON(i);
  329. }
  330. vgrow(&fn->con, ++fn->ncon);
  331. fn->con[i] = *c0;
  332. return CON(i);
  333. }
  334. Ref
  335. getcon(int64_t val, Fn *fn)
  336. {
  337. int c;
  338. for (c=1; c<fn->ncon; c++)
  339. if (fn->con[c].type == CBits
  340. && fn->con[c].bits.i == val)
  341. return CON(c);
  342. vgrow(&fn->con, ++fn->ncon);
  343. fn->con[c] = (Con){.type = CBits, .bits.i = val};
  344. return CON(c);
  345. }
  346. int
  347. addcon(Con *c0, Con *c1, int m)
  348. {
  349. if (m != 1 && c1->type == CAddr)
  350. return 0;
  351. if (c0->type == CUndef) {
  352. *c0 = *c1;
  353. c0->bits.i *= m;
  354. } else {
  355. if (c1->type == CAddr) {
  356. if (c0->type == CAddr)
  357. return 0;
  358. c0->type = CAddr;
  359. c0->sym = c1->sym;
  360. }
  361. c0->bits.i += c1->bits.i * m;
  362. }
  363. return 1;
  364. }
  365. void
  366. salloc(Ref rt, Ref rs, Fn *fn)
  367. {
  368. Ref r0, r1;
  369. int64_t sz;
  370. /* we need to make sure
  371. * the stack remains aligned
  372. * (rsp = 0) mod 16
  373. */
  374. fn->dynalloc = 1;
  375. if (rtype(rs) == RCon) {
  376. sz = fn->con[rs.val].bits.i;
  377. if (sz < 0 || sz >= INT_MAX-15)
  378. err("invalid alloc size %"PRId64, sz);
  379. sz = (sz + 15) & -16;
  380. emit(Osalloc, Kl, rt, getcon(sz, fn), R);
  381. } else {
  382. /* r0 = (r + 15) & -16 */
  383. r0 = newtmp("isel", Kl, fn);
  384. r1 = newtmp("isel", Kl, fn);
  385. emit(Osalloc, Kl, rt, r0, R);
  386. emit(Oand, Kl, r0, r1, getcon(-16, fn));
  387. emit(Oadd, Kl, r1, rs, getcon(15, fn));
  388. if (fn->tmp[rs.val].slot != -1)
  389. err("unlikely alloc argument %%%s for %%%s",
  390. fn->tmp[rs.val].name, fn->tmp[rt.val].name);
  391. }
  392. }
  393. void
  394. bsinit(BSet *bs, uint n)
  395. {
  396. n = (n + NBit-1) / NBit;
  397. bs->nt = n;
  398. bs->t = alloc(n * sizeof bs->t[0]);
  399. }
  400. MAKESURE(NBit_is_64, NBit == 64);
  401. inline static uint
  402. popcnt(bits b)
  403. {
  404. b = (b & 0x5555555555555555) + ((b>>1) & 0x5555555555555555);
  405. b = (b & 0x3333333333333333) + ((b>>2) & 0x3333333333333333);
  406. b = (b & 0x0f0f0f0f0f0f0f0f) + ((b>>4) & 0x0f0f0f0f0f0f0f0f);
  407. b += (b>>8);
  408. b += (b>>16);
  409. b += (b>>32);
  410. return b & 0xff;
  411. }
  412. inline static int
  413. firstbit(bits b)
  414. {
  415. int n;
  416. n = 0;
  417. if (!(b & 0xffffffff)) {
  418. n += 32;
  419. b >>= 32;
  420. }
  421. if (!(b & 0xffff)) {
  422. n += 16;
  423. b >>= 16;
  424. }
  425. if (!(b & 0xff)) {
  426. n += 8;
  427. b >>= 8;
  428. }
  429. if (!(b & 0xf)) {
  430. n += 4;
  431. b >>= 4;
  432. }
  433. n += (char[16]){4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0}[b & 0xf];
  434. return n;
  435. }
  436. uint
  437. bscount(BSet *bs)
  438. {
  439. uint i, n;
  440. n = 0;
  441. for (i=0; i<bs->nt; i++)
  442. n += popcnt(bs->t[i]);
  443. return n;
  444. }
  445. static inline uint
  446. bsmax(BSet *bs)
  447. {
  448. return bs->nt * NBit;
  449. }
  450. void
  451. bsset(BSet *bs, uint elt)
  452. {
  453. assert(elt < bsmax(bs));
  454. bs->t[elt/NBit] |= BIT(elt%NBit);
  455. }
  456. void
  457. bsclr(BSet *bs, uint elt)
  458. {
  459. assert(elt < bsmax(bs));
  460. bs->t[elt/NBit] &= ~BIT(elt%NBit);
  461. }
  462. #define BSOP(f, op) \
  463. void \
  464. f(BSet *a, BSet *b) \
  465. { \
  466. uint i; \
  467. \
  468. assert(a->nt == b->nt); \
  469. for (i=0; i<a->nt; i++) \
  470. a->t[i] op b->t[i]; \
  471. }
  472. BSOP(bscopy, =)
  473. BSOP(bsunion, |=)
  474. BSOP(bsinter, &=)
  475. BSOP(bsdiff, &= ~)
  476. int
  477. bsequal(BSet *a, BSet *b)
  478. {
  479. uint i;
  480. assert(a->nt == b->nt);
  481. for (i=0; i<a->nt; i++)
  482. if (a->t[i] != b->t[i])
  483. return 0;
  484. return 1;
  485. }
  486. void
  487. bszero(BSet *bs)
  488. {
  489. memset(bs->t, 0, bs->nt * sizeof bs->t[0]);
  490. }
  491. /* iterates on a bitset, use as follows
  492. *
  493. * for (i=0; bsiter(set, &i); i++)
  494. * use(i);
  495. *
  496. */
  497. int
  498. bsiter(BSet *bs, int *elt)
  499. {
  500. bits b;
  501. uint t, i;
  502. i = *elt;
  503. t = i/NBit;
  504. if (t >= bs->nt)
  505. return 0;
  506. b = bs->t[t];
  507. b &= ~(BIT(i%NBit) - 1);
  508. while (!b) {
  509. ++t;
  510. if (t >= bs->nt)
  511. return 0;
  512. b = bs->t[t];
  513. }
  514. *elt = NBit*t + firstbit(b);
  515. return 1;
  516. }
  517. void
  518. dumpts(BSet *bs, Tmp *tmp, FILE *f)
  519. {
  520. int t;
  521. fprintf(f, "[");
  522. for (t=Tmp0; bsiter(bs, &t); t++)
  523. fprintf(f, " %s", tmp[t].name);
  524. fprintf(f, " ]\n");
  525. }
  526. void
  527. runmatch(uchar *code, Num *tn, Ref ref, Ref *var)
  528. {
  529. Ref stkbuf[20], *stk;
  530. uchar *s, *pc;
  531. int bc, i;
  532. int n, nl, nr;
  533. assert(rtype(ref) == RTmp);
  534. stk = stkbuf;
  535. pc = code;
  536. while ((bc = *pc))
  537. switch (bc) {
  538. case 1: /* pushsym */
  539. case 2: /* push */
  540. assert(stk < &stkbuf[20]);
  541. assert(rtype(ref) == RTmp);
  542. nl = tn[ref.val].nl;
  543. nr = tn[ref.val].nr;
  544. if (bc == 1 && nl > nr) {
  545. *stk++ = tn[ref.val].l;
  546. ref = tn[ref.val].r;
  547. } else {
  548. *stk++ = tn[ref.val].r;
  549. ref = tn[ref.val].l;
  550. }
  551. pc++;
  552. break;
  553. case 3: /* set */
  554. var[*++pc] = ref;
  555. if (*(pc + 1) == 0)
  556. return;
  557. /* fall through */
  558. case 4: /* pop */
  559. assert(stk > &stkbuf[0]);
  560. ref = *--stk;
  561. pc++;
  562. break;
  563. case 5: /* switch */
  564. assert(rtype(ref) == RTmp);
  565. n = tn[ref.val].n;
  566. s = pc + 1;
  567. for (i=*s++; i>0; i--, s++)
  568. if (n == *s++)
  569. break;
  570. pc += *s;
  571. break;
  572. default: /* jump */
  573. assert(bc >= 10);
  574. pc = code + (bc - 10);
  575. break;
  576. }
  577. }