pass.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. #include "l.h"
  2. void
  3. dodata(void)
  4. {
  5. int i;
  6. Sym *s;
  7. Prog *p;
  8. long t, u;
  9. if(debug['v'])
  10. Bprint(&bso, "%5.2f dodata\n", cputime());
  11. Bflush(&bso);
  12. for(p = datap; p != P; p = p->link) {
  13. s = p->from.sym;
  14. if(s->type == SBSS)
  15. s->type = SDATA;
  16. if(s->type != SDATA)
  17. diag("initialize non-data (%d): %s\n%P",
  18. s->type, s->name, p);
  19. t = p->from.offset + p->from.displace;
  20. if(t > s->value)
  21. diag("initialize bounds (%ld): %s\n%P",
  22. s->value, s->name, p);
  23. }
  24. /* allocate small guys */
  25. datsize = 0;
  26. for(i=0; i<NHASH; i++)
  27. for(s = hash[i]; s != S; s = s->link) {
  28. if(s->type != SDATA)
  29. if(s->type != SBSS)
  30. continue;
  31. t = s->value;
  32. if(t == 0) {
  33. diag("%s: no size", s->name);
  34. t = 1;
  35. }
  36. t = rnd(t, 4);;
  37. s->value = t;
  38. if(t > MINSIZ)
  39. continue;
  40. s->value = datsize;
  41. datsize += t;
  42. s->type = SDATA1;
  43. }
  44. /* allocate the rest of the data */
  45. for(i=0; i<NHASH; i++)
  46. for(s = hash[i]; s != S; s = s->link) {
  47. if(s->type != SDATA) {
  48. if(s->type == SDATA1)
  49. s->type = SDATA;
  50. continue;
  51. }
  52. t = s->value;
  53. s->value = datsize;
  54. datsize += t;
  55. }
  56. if(debug['j']) {
  57. /*
  58. * pad data with bss that fits up to next
  59. * 8k boundary, then push data to 8k
  60. */
  61. u = rnd(datsize, 8192);
  62. u -= datsize;
  63. for(i=0; i<NHASH; i++)
  64. for(s = hash[i]; s != S; s = s->link) {
  65. if(s->type != SBSS)
  66. continue;
  67. t = s->value;
  68. if(t > u)
  69. continue;
  70. u -= t;
  71. s->value = datsize;
  72. s->type = SDATA;
  73. datsize += t;
  74. }
  75. datsize += u;
  76. }
  77. /* now the bss */
  78. bsssize = 0;
  79. for(i=0; i<NHASH; i++)
  80. for(s = hash[i]; s != S; s = s->link) {
  81. if(s->type != SBSS)
  82. continue;
  83. t = s->value;
  84. s->value = bsssize + datsize;
  85. bsssize += t;
  86. }
  87. xdefine("bdata", SDATA, 0L);
  88. xdefine("edata", SDATA, datsize);
  89. xdefine("end", SBSS, datsize+bsssize);
  90. }
  91. Prog*
  92. brchain(Prog *p)
  93. {
  94. int i;
  95. for(i=0; i<20; i++) {
  96. if(p == P || p->as != ABRA)
  97. return p;
  98. p = p->pcond;
  99. }
  100. return P;
  101. }
  102. void
  103. follow(void)
  104. {
  105. Prog *p;
  106. long o;
  107. Sym *s;
  108. if(debug['v'])
  109. Bprint(&bso, "%5.2f follow\n", cputime());
  110. Bflush(&bso);
  111. firstp = prg();
  112. lastp = firstp;
  113. xfol(textp);
  114. lastp->link = P;
  115. firstp = firstp->link;
  116. o = 0; /* set */
  117. for(p = firstp; p != P; p = p->link) {
  118. if(p->as == ATEXT)
  119. curtext = p;
  120. if(p->as == ABCASE) { /* initialization for dodata */
  121. s = p->from.sym;
  122. if(s->type == SBSS)
  123. s->type = SDATA;
  124. if(s->type != SDATA)
  125. diag("BCASE of non-data: %s in %s\n%P",
  126. s->name, TNAME, p);
  127. }
  128. p->stkoff = -1; /* initialization for stkoff */
  129. if(p->as == ATEXT) {
  130. p->stkoff = 0;
  131. o = p->to.offset;
  132. continue;
  133. }
  134. if(p->as == AADJSP && p->from.offset == 0) {
  135. p->stkoff = o;
  136. continue;
  137. }
  138. }
  139. }
  140. void
  141. xfol(Prog *p)
  142. {
  143. Prog *q;
  144. int i;
  145. enum as a;
  146. loop:
  147. if(p == P)
  148. return;
  149. if(p->as == ATEXT)
  150. curtext = p;
  151. if(p->as == ABRA)
  152. if((q = p->pcond) != P) {
  153. p->mark = 1;
  154. p = q;
  155. if(p->mark == 0)
  156. goto loop;
  157. }
  158. if(p->mark) {
  159. /* copy up to 4 instructions to avoid branch */
  160. for(i=0,q=p; i<4; i++,q=q->link) {
  161. if(q == P)
  162. break;
  163. if(q == lastp)
  164. break;
  165. a = q->as;
  166. if(a == ANOP) {
  167. i--;
  168. continue;
  169. }
  170. if(a == ABRA || a == ARTS || a == ARTE)
  171. break;
  172. if(q->pcond == P || q->pcond->mark)
  173. continue;
  174. if(a == ABSR || a == ABCASE || a == ADBF)
  175. continue;
  176. for(;;) {
  177. if(p->as == ANOP) {
  178. p = p->link;
  179. continue;
  180. }
  181. q = copyp(p);
  182. p = p->link;
  183. q->mark = 1;
  184. lastp->link = q;
  185. lastp = q;
  186. if(q->as != a || q->pcond == P || q->pcond->mark)
  187. continue;
  188. q->as = relinv(q->as);
  189. p = q->pcond;
  190. q->pcond = q->link;
  191. q->link = p;
  192. xfol(q->link);
  193. p = q->link;
  194. if(p->mark)
  195. return;
  196. goto loop;
  197. }
  198. } /* */
  199. q = prg();
  200. q->as = ABRA;
  201. q->line = p->line;
  202. q->to.type = D_BRANCH;
  203. q->to.offset = p->pc;
  204. q->pcond = p;
  205. p = q;
  206. }
  207. p->mark = 1;
  208. lastp->link = p;
  209. lastp = p;
  210. a = p->as;
  211. if(a == ARTS || a == ABRA || a == ARTE)
  212. return;
  213. if(p->pcond != P)
  214. if(a != ABSR) {
  215. q = brchain(p->link);
  216. if(q != P && q->mark)
  217. if(a != ABCASE && a != ADBF) {
  218. p->as = relinv(a);
  219. p->link = p->pcond;
  220. p->pcond = q;
  221. }
  222. xfol(p->link);
  223. q = brchain(p->pcond);
  224. if(q->mark) {
  225. p->pcond = q;
  226. return;
  227. }
  228. p = q;
  229. goto loop;
  230. }
  231. p = p->link;
  232. goto loop;
  233. }
  234. int
  235. relinv(int a)
  236. {
  237. switch(a) {
  238. case ABEQ: return ABNE;
  239. case ABNE: return ABEQ;
  240. case ABLE: return ABGT;
  241. case ABLS: return ABHI;
  242. case ABLT: return ABGE;
  243. case ABMI: return ABPL;
  244. case ABGE: return ABLT;
  245. case ABPL: return ABMI;
  246. case ABGT: return ABLE;
  247. case ABHI: return ABLS;
  248. case ABCS: return ABCC;
  249. case ABCC: return ABCS;
  250. case AFBEQ: return AFBNE;
  251. case AFBF: return AFBT;
  252. case AFBGE: return AFBLT;
  253. case AFBGT: return AFBLE;
  254. case AFBLE: return AFBGT;
  255. case AFBLT: return AFBGE;
  256. case AFBNE: return AFBEQ;
  257. case AFBT: return AFBF;
  258. }
  259. diag("unknown relation: %s in %s", anames[a], TNAME);
  260. return a;
  261. }
  262. void
  263. patch(void)
  264. {
  265. long c;
  266. Prog *p, *q;
  267. Sym *s;
  268. long vexit;
  269. if(debug['v'])
  270. Bprint(&bso, "%5.2f mkfwd\n", cputime());
  271. Bflush(&bso);
  272. mkfwd();
  273. if(debug['v'])
  274. Bprint(&bso, "%5.2f patch\n", cputime());
  275. Bflush(&bso);
  276. s = lookup("exit", 0);
  277. vexit = s->value;
  278. for(p = firstp; p != P; p = p->link) {
  279. if(p->as == ATEXT)
  280. curtext = p;
  281. if((p->as == ABSR || p->as == ARTS) && p->to.sym != S) {
  282. s = p->to.sym;
  283. if(s->type != STEXT) {
  284. diag("undefined: %s in %s", s->name, TNAME);
  285. s->type = STEXT;
  286. s->value = vexit;
  287. }
  288. p->to.offset = s->value;
  289. p->to.type = D_BRANCH;
  290. }
  291. if(p->to.type != D_BRANCH)
  292. continue;
  293. c = p->to.offset;
  294. for(q = firstp; q != P;) {
  295. if(q->forwd != P)
  296. if(c >= q->forwd->pc) {
  297. q = q->forwd;
  298. continue;
  299. }
  300. if(c == q->pc)
  301. break;
  302. q = q->link;
  303. }
  304. if(q == P) {
  305. diag("branch out of range in %s\n%P", TNAME, p);
  306. p->to.type = D_NONE;
  307. }
  308. p->pcond = q;
  309. }
  310. for(p = firstp; p != P; p = p->link) {
  311. if(p->as == ATEXT)
  312. curtext = p;
  313. p->mark = 0; /* initialization for follow */
  314. if(p->pcond != P) {
  315. p->pcond = brloop(p->pcond);
  316. if(p->pcond != P)
  317. if(p->to.type == D_BRANCH)
  318. p->to.offset = p->pcond->pc;
  319. }
  320. }
  321. }
  322. #define LOG 5
  323. void
  324. mkfwd(void)
  325. {
  326. Prog *p;
  327. int i;
  328. long dwn[LOG], cnt[LOG];
  329. Prog *lst[LOG];
  330. for(i=0; i<LOG; i++) {
  331. if(i == 0)
  332. cnt[i] = 1; else
  333. cnt[i] = LOG * cnt[i-1];
  334. dwn[i] = 1;
  335. lst[i] = P;
  336. }
  337. i = 0;
  338. for(p = firstp; p != P; p = p->link) {
  339. if(p->as == ATEXT)
  340. curtext = p;
  341. i--;
  342. if(i < 0)
  343. i = LOG-1;
  344. p->forwd = P;
  345. dwn[i]--;
  346. if(dwn[i] <= 0) {
  347. dwn[i] = cnt[i];
  348. if(lst[i] != P)
  349. lst[i]->forwd = p;
  350. lst[i] = p;
  351. }
  352. }
  353. }
  354. Prog*
  355. brloop(Prog *p)
  356. {
  357. int c;
  358. Prog *q;
  359. c = 0;
  360. for(q = p; q != P; q = q->pcond) {
  361. if(q->as != ABRA)
  362. break;
  363. c++;
  364. if(c >= 5000)
  365. return P;
  366. }
  367. return q;
  368. }
  369. void
  370. dostkoff(void)
  371. {
  372. Prog *p, *q;
  373. long s, t;
  374. int a;
  375. Optab *o;
  376. if(debug['v'])
  377. Bprint(&bso, "%5.2f stkoff\n", cputime());
  378. Bflush(&bso);
  379. s = 0;
  380. for(p = firstp; p != P; p = p->link) {
  381. if(p->as == ATEXT) {
  382. curtext = p;
  383. s = p->to.offset;
  384. if(s == 0)
  385. continue;
  386. p = appendp(p);
  387. p->as = AADJSP;
  388. p->from.type = D_CONST;
  389. p->from.offset = s;
  390. p->stkoff = 0;
  391. continue;
  392. }
  393. for(q = p; q != P; q = q->pcond) {
  394. if(q->as == ATEXT)
  395. break;
  396. if(q->stkoff >= 0)
  397. if(q->stkoff != s)
  398. diag("stack offset %ld is %ld sb %ld in %s\n%P",
  399. q->pc, q->stkoff, s, q, TNAME, p);
  400. q->stkoff = s;
  401. }
  402. o = &optab[p->as];
  403. if(p->to.type == D_TOS)
  404. s -= o->dstsp;
  405. if(p->from.type == D_TOS)
  406. s -= o->srcsp;
  407. if(p->as == AADJSP)
  408. s += p->from.offset;
  409. if(p->as == APEA)
  410. s += 4;
  411. for(q = p->link; q != P; q = q->pcond) {
  412. if(q->as == ATEXT) {
  413. q = P;
  414. break;
  415. }
  416. if(q->stkoff >= 0)
  417. break;
  418. }
  419. if(q == P || q->stkoff == s)
  420. continue;
  421. if(p->as == ABRA || p->as == ARTS || p->as == ARTE) {
  422. s = q->stkoff;
  423. continue;
  424. }
  425. if(p->link->as == ABCASE)
  426. diag("BCASE with stack offset in %s", TNAME);
  427. t = q->stkoff - s;
  428. s = q->stkoff;
  429. p = appendp(p);
  430. p->as = AADJSP;
  431. p->stkoff = s - t;
  432. p->from.type = D_CONST;
  433. p->from.offset = t;
  434. }
  435. for(p = firstp; p != P; p = p->link) {
  436. if(p->as == ATEXT)
  437. curtext = p;
  438. a = p->from.type & D_MASK;
  439. if(a == D_AUTO)
  440. p->from.offset += p->stkoff;
  441. if(a == D_PARAM)
  442. p->from.offset += p->stkoff + 4;
  443. a = p->to.type & D_MASK;
  444. if(a == D_AUTO)
  445. p->to.offset += p->stkoff;
  446. if(a == D_PARAM)
  447. p->to.offset += p->stkoff + 4;
  448. if(p->as != ARTS)
  449. continue;
  450. if(p->stkoff == 0)
  451. continue;
  452. q = p;
  453. p = appendp(p);
  454. p->as = ARTS;
  455. p->stkoff = 0;
  456. q->as = AADJSP;
  457. q->from.type = D_CONST;
  458. q->from.offset = -q->stkoff;
  459. }
  460. }
  461. long
  462. atolwhex(char *s)
  463. {
  464. long n;
  465. int f;
  466. n = 0;
  467. f = 0;
  468. while(*s == ' ' || *s == '\t')
  469. s++;
  470. if(*s == '-' || *s == '+') {
  471. if(*s++ == '-')
  472. f = 1;
  473. while(*s == ' ' || *s == '\t')
  474. s++;
  475. }
  476. if(s[0]=='0' && s[1]){
  477. if(s[1]=='x' || s[1]=='X'){
  478. s += 2;
  479. for(;;){
  480. if(*s >= '0' && *s <= '9')
  481. n = n*16 + *s++ - '0';
  482. else if(*s >= 'a' && *s <= 'f')
  483. n = n*16 + *s++ - 'a' + 10;
  484. else if(*s >= 'A' && *s <= 'F')
  485. n = n*16 + *s++ - 'A' + 10;
  486. else
  487. break;
  488. }
  489. } else
  490. while(*s >= '0' && *s <= '7')
  491. n = n*8 + *s++ - '0';
  492. } else
  493. while(*s >= '0' && *s <= '9')
  494. n = n*10 + *s++ - '0';
  495. if(f)
  496. n = -n;
  497. return n;
  498. }
  499. void
  500. undef(void)
  501. {
  502. int i;
  503. Sym *s;
  504. for(i=0; i<NHASH; i++)
  505. for(s = hash[i]; s != S; s = s->link)
  506. if(s->type == SXREF)
  507. diag("%s: not defined", s->name);
  508. }