swt.c 9.5 KB

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