swt.c 11 KB

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