pass.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. #include "l.h"
  2. void
  3. dodata(void)
  4. {
  5. int i, t, size;
  6. Sym *s;
  7. Prog *p, *p1;
  8. long orig, orig1, v;
  9. vlong vv;
  10. if(debug['v'])
  11. Bprint(&bso, "%5.2f dodata\n", cputime());
  12. Bflush(&bso);
  13. for(p = datap; p != P; p = p->link) {
  14. s = p->from.sym;
  15. if(p->as == ADYNT || p->as == AINIT)
  16. s->value = dtype;
  17. if(s->type == SBSS)
  18. s->type = SDATA;
  19. if(s->type != SDATA)
  20. diag("initialize non-data (%d): %s\n%P\n",
  21. s->type, s->name, p);
  22. v = p->from.offset + p->reg;
  23. if(v > s->value)
  24. diag("initialize bounds (%ld): %s\n%P\n",
  25. s->value, s->name, p);
  26. }
  27. /*
  28. * pass 1
  29. * assign 'small' variables to data segment
  30. * (rational is that data segment is more easily
  31. * addressed through offset on REGSB)
  32. */
  33. orig = 0;
  34. for(i=0; i<NHASH; i++)
  35. for(s = hash[i]; s != S; s = s->link) {
  36. t = s->type;
  37. if(t != SDATA && t != SBSS)
  38. continue;
  39. v = s->value;
  40. if(v == 0) {
  41. diag("%s: no size\n", s->name);
  42. v = 1;
  43. }
  44. while(v & 3)
  45. v++;
  46. s->value = v;
  47. if(v > MINSIZ)
  48. continue;
  49. if (v >= 8)
  50. orig = rnd(orig, 8);
  51. s->value = orig;
  52. orig += v;
  53. s->type = SDATA1;
  54. }
  55. orig = rnd(orig, 8);
  56. orig1 = orig;
  57. /*
  58. * pass 2
  59. * assign 'data' variables to data segment
  60. */
  61. for(i=0; i<NHASH; i++)
  62. for(s = hash[i]; s != S; s = s->link) {
  63. t = s->type;
  64. if(t != SDATA) {
  65. if(t == SDATA1)
  66. s->type = SDATA;
  67. continue;
  68. }
  69. v = s->value;
  70. if (v >= 8)
  71. orig = rnd(orig, 8);
  72. s->value = orig;
  73. orig += v;
  74. s->type = SDATA1;
  75. }
  76. orig = rnd(orig, 8);
  77. datsize = orig;
  78. /*
  79. * pass 3
  80. * everything else to bss segment
  81. */
  82. for(i=0; i<NHASH; i++)
  83. for(s = hash[i]; s != S; s = s->link) {
  84. if(s->type != SBSS)
  85. continue;
  86. v = s->value;
  87. if (v >= 8)
  88. orig = rnd(orig, 8);
  89. s->value = orig;
  90. orig += v;
  91. }
  92. orig = rnd(orig, 8);
  93. bsssize = orig-datsize;
  94. /*
  95. * pass 4
  96. * add literals to all large values.
  97. * at this time:
  98. * small data is allocated DATA
  99. * large data is allocated DATA1
  100. * large bss is allocated BSS
  101. * the new literals are loaded between
  102. * small data and large data.
  103. */
  104. orig = 0;
  105. for(p = firstp; p != P; p = p->link) {
  106. if(p->as != AMOVQ)
  107. continue;
  108. if(p->from.type != D_CONST)
  109. continue;
  110. if(s = p->from.sym) {
  111. t = s->type;
  112. if(t != SDATA && t != SDATA1 && t != SBSS)
  113. continue;
  114. t = p->from.name;
  115. if(t != D_EXTERN && t != D_STATIC)
  116. continue;
  117. v = s->value + p->from.offset;
  118. size = 4;
  119. if(v >= 0 && v <= 0xffff)
  120. continue;
  121. if(!strcmp(s->name, "setSB"))
  122. continue;
  123. /* size should be 19 max */
  124. if(strlen(s->name) >= 10) /* has loader address */
  125. sprint(literal, "$%lux.%lux", (long)s, (long)p->from.offset);
  126. else
  127. sprint(literal, "$%s.%d.%lux", s->name, s->version, (long)p->from.offset);
  128. } else {
  129. if(p->from.name != D_NONE)
  130. continue;
  131. if(p->from.reg != NREG)
  132. continue;
  133. vv = p->from.offset;
  134. if(vv >= -0x8000LL && vv <= 0x7fff)
  135. continue;
  136. if(!(vv & 0xffff))
  137. continue;
  138. size = 8;
  139. if (vv <= 0x7FFFFFFFLL && vv >= -0x80000000LL)
  140. size = 4;
  141. /* size should be 17 max */
  142. sprint(literal, "$%llux", vv);
  143. }
  144. s = lookup(literal, 0);
  145. if(s->type == 0) {
  146. s->type = SDATA;
  147. orig = rnd(orig, size);
  148. s->value = orig1+orig;
  149. orig += size;
  150. p1 = prg();
  151. p1->line = p->line;
  152. p1->as = ADATA;
  153. p1->from.type = D_OREG;
  154. p1->from.sym = s;
  155. p1->from.name = D_EXTERN;
  156. p1->reg = size;
  157. p1->to = p->from;
  158. p1->link = datap;
  159. datap = p1;
  160. if(debug['C'])
  161. Bprint(&bso, "literal %P for %P\n", p1, p);
  162. }
  163. if(s->type != SDATA)
  164. diag("literal not data: %s", s->name);
  165. if (size == 4)
  166. p->as = AMOVL;
  167. p->from.type = D_OREG;
  168. p->from.sym = s;
  169. p->from.name = D_EXTERN;
  170. p->from.offset = 0;
  171. continue;
  172. }
  173. orig = rnd(orig, 8);
  174. /*
  175. * pass 5
  176. * re-adjust offsets
  177. */
  178. for(i=0; i<NHASH; i++)
  179. for(s = hash[i]; s != S; s = s->link) {
  180. t = s->type;
  181. if(t == SBSS) {
  182. s->value += orig;
  183. continue;
  184. }
  185. if(t == SDATA1) {
  186. s->type = SDATA;
  187. s->value += orig;
  188. continue;
  189. }
  190. }
  191. datsize += orig;
  192. if (debug['v'] || debug['z'])
  193. Bprint(&bso, "datsize = %lux, bsssize = %lux\n", datsize, bsssize);
  194. xdefine("setSB", SDATA, 0L+BIG);
  195. xdefine("bdata", SDATA, 0L);
  196. xdefine("edata", SDATA, datsize);
  197. xdefine("end", SBSS, datsize+bsssize);
  198. xdefine("etext", STEXT, 0L);
  199. }
  200. void
  201. undef(void)
  202. {
  203. int i;
  204. Sym *s;
  205. for(i=0; i<NHASH; i++)
  206. for(s = hash[i]; s != S; s = s->link)
  207. if(s->type == SXREF)
  208. diag("%s: not defined\n", s->name);
  209. }
  210. void
  211. follow(void)
  212. {
  213. if(debug['v'])
  214. Bprint(&bso, "%5.2f follow\n", cputime());
  215. Bflush(&bso);
  216. firstp = prg();
  217. lastp = firstp;
  218. xfol(textp);
  219. firstp = firstp->link;
  220. lastp->link = P;
  221. }
  222. void
  223. xfol(Prog *p)
  224. {
  225. Prog *q, *r;
  226. int a, i;
  227. loop:
  228. if(p == P)
  229. return;
  230. a = p->as;
  231. if(a == ATEXT)
  232. curtext = p;
  233. if(a == AJMP) {
  234. q = p->cond;
  235. if(q != P) {
  236. p->mark = FOLL;
  237. p = q;
  238. if(!(p->mark & FOLL))
  239. goto loop;
  240. }
  241. }
  242. if(p->mark & FOLL) {
  243. for(i=0,q=p; i<4; i++,q=q->link) {
  244. if(q == lastp)
  245. break;
  246. a = q->as;
  247. if(a == ANOP) {
  248. i--;
  249. continue;
  250. }
  251. if(a == AJMP || a == ARET || a == AREI)
  252. goto copy;
  253. if(!q->cond || (q->cond->mark&FOLL))
  254. continue;
  255. if(a != ABEQ && a != ABNE)
  256. continue;
  257. copy:
  258. for(;;) {
  259. r = prg();
  260. *r = *p;
  261. if(!(r->mark&FOLL))
  262. print("cant happen 1\n");
  263. r->mark = FOLL;
  264. if(p != q) {
  265. p = p->link;
  266. lastp->link = r;
  267. lastp = r;
  268. continue;
  269. }
  270. lastp->link = r;
  271. lastp = r;
  272. if(a == AJMP || a == ARET || a == AREI)
  273. return;
  274. r->as = ABNE;
  275. if(a == ABNE)
  276. r->as = ABEQ;
  277. r->cond = p->link;
  278. r->link = p->cond;
  279. if(!(r->link->mark&FOLL))
  280. xfol(r->link);
  281. if(!(r->cond->mark&FOLL))
  282. print("cant happen 2\n");
  283. return;
  284. }
  285. }
  286. a = AJMP;
  287. q = prg();
  288. q->as = a;
  289. q->line = p->line;
  290. q->to.type = D_BRANCH;
  291. q->to.offset = p->pc;
  292. q->cond = p;
  293. p = q;
  294. }
  295. p->mark = FOLL;
  296. lastp->link = p;
  297. lastp = p;
  298. if(a == AJMP || a == ARET || a == AREI)
  299. return;
  300. if(p->cond != P)
  301. if(a != AJSR && p->link != P) {
  302. xfol(p->link);
  303. p = p->cond;
  304. if(p == P || (p->mark&FOLL))
  305. return;
  306. goto loop;
  307. }
  308. p = p->link;
  309. goto loop;
  310. }
  311. void
  312. patch(void)
  313. {
  314. long c, vexit;
  315. Prog *p, *q;
  316. Sym *s;
  317. int a;
  318. if(debug['v'])
  319. Bprint(&bso, "%5.2f patch\n", cputime());
  320. Bflush(&bso);
  321. mkfwd();
  322. s = lookup("exit", 0);
  323. vexit = s->value;
  324. for(p = firstp; p != P; p = p->link) {
  325. a = p->as;
  326. if(a == ATEXT)
  327. curtext = p;
  328. if((a == AJSR || a == AJMP || a == ARET) &&
  329. p->to.type != D_BRANCH && p->to.sym != S) {
  330. s = p->to.sym;
  331. if(s->type != STEXT) {
  332. diag("undefined: %s\n%P\n", s->name, p);
  333. s->type = STEXT;
  334. s->value = vexit;
  335. }
  336. p->to.offset = s->value;
  337. p->to.type = D_BRANCH;
  338. }
  339. if(p->to.type != D_BRANCH)
  340. continue;
  341. c = p->to.offset;
  342. for(q = firstp; q != P;) {
  343. if(q->forwd != P)
  344. if(c >= q->forwd->pc) {
  345. q = q->forwd;
  346. continue;
  347. }
  348. if(c == q->pc)
  349. break;
  350. q = q->link;
  351. }
  352. if(q == P) {
  353. diag("branch out of range %ld\n%P\n", c, p);
  354. p->to.type = D_NONE;
  355. }
  356. p->cond = q;
  357. }
  358. for(p = firstp; p != P; p = p->link) {
  359. if(p->as == ATEXT)
  360. curtext = p;
  361. if(p->cond != P) {
  362. p->cond = brloop(p->cond);
  363. if(p->cond != P)
  364. if(p->to.type == D_BRANCH)
  365. p->to.offset = p->cond->pc;
  366. }
  367. }
  368. }
  369. #define LOG 5
  370. void
  371. mkfwd(void)
  372. {
  373. Prog *p;
  374. long dwn[LOG], cnt[LOG], i;
  375. Prog *lst[LOG];
  376. for(i=0; i<LOG; i++) {
  377. if(i == 0)
  378. cnt[i] = 1; else
  379. cnt[i] = LOG * cnt[i-1];
  380. dwn[i] = 1;
  381. lst[i] = P;
  382. }
  383. i = 0;
  384. for(p = firstp; p != P; p = p->link) {
  385. if(p->as == ATEXT)
  386. curtext = p;
  387. i--;
  388. if(i < 0)
  389. i = LOG-1;
  390. p->forwd = P;
  391. dwn[i]--;
  392. if(dwn[i] <= 0) {
  393. dwn[i] = cnt[i];
  394. if(lst[i] != P)
  395. lst[i]->forwd = p;
  396. lst[i] = p;
  397. }
  398. }
  399. }
  400. Prog*
  401. brloop(Prog *p)
  402. {
  403. Prog *q;
  404. int c;
  405. for(c=0; p!=P;) {
  406. if(p->as != AJMP)
  407. return p;
  408. q = p->cond;
  409. if(q <= p) {
  410. c++;
  411. if(q == p || c > 50)
  412. break;
  413. }
  414. p = q;
  415. }
  416. return P;
  417. }
  418. long
  419. atolwhex(char *s)
  420. {
  421. long n;
  422. int f;
  423. n = 0;
  424. f = 0;
  425. while(*s == ' ' || *s == '\t')
  426. s++;
  427. if(*s == '-' || *s == '+') {
  428. if(*s++ == '-')
  429. f = 1;
  430. while(*s == ' ' || *s == '\t')
  431. s++;
  432. }
  433. if(s[0]=='0' && s[1]){
  434. if(s[1]=='x' || s[1]=='X'){
  435. s += 2;
  436. for(;;){
  437. if(*s >= '0' && *s <= '9')
  438. n = n*16 + *s++ - '0';
  439. else if(*s >= 'a' && *s <= 'f')
  440. n = n*16 + *s++ - 'a' + 10;
  441. else if(*s >= 'A' && *s <= 'F')
  442. n = n*16 + *s++ - 'A' + 10;
  443. else
  444. break;
  445. }
  446. } else
  447. while(*s >= '0' && *s <= '7')
  448. n = n*8 + *s++ - '0';
  449. } else
  450. while(*s >= '0' && *s <= '9')
  451. n = n*10 + *s++ - '0';
  452. if(f)
  453. n = -n;
  454. return n;
  455. }
  456. long
  457. rnd(long v, long r)
  458. {
  459. long c;
  460. if(r <= 0)
  461. return v;
  462. v += r - 1;
  463. c = v % r;
  464. if(c < 0)
  465. c += r;
  466. v -= c;
  467. return v;
  468. }