swt.c 8.8 KB

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