swt.c 9.1 KB

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