pass.c 8.5 KB

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