span.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. #include "l.h"
  2. void
  3. span(void)
  4. {
  5. Prog *p, *q;
  6. long v, c, idat;
  7. Optab *o;
  8. int m, n;
  9. xdefine("etext", STEXT, 0L);
  10. xdefine("a6base", STEXT, 0L);
  11. idat = INITDAT;
  12. for(p = firstp; p != P; p = p->link) {
  13. if(p->as == ATEXT)
  14. curtext = p;
  15. n = 0;
  16. if((q = p->pcond) != P)
  17. if(q->back != 2)
  18. n = 1;
  19. p->back = n;
  20. if(p->as == AADJSP) {
  21. p->to.type = D_A0+7;
  22. v = -p->from.offset;
  23. p->from.offset = v;
  24. if((v < -8 && v >= -32768L) || (v > 8 && v < 32768L)) {
  25. p->as = ALEA;
  26. p->from.type = I_INDIR | (D_A0+7);
  27. continue;
  28. }
  29. p->as = AADDL;
  30. if(v < 0) {
  31. p->as = ASUBL;
  32. v = -v;
  33. p->from.offset = v;
  34. }
  35. if(v >= 0 && v <= 8)
  36. p->from.type = D_QUICK;
  37. if(v == 0)
  38. p->as = ANOP;
  39. }
  40. }
  41. n = 0;
  42. start:
  43. if(debug['v'])
  44. Bprint(&bso, "%5.2f span\n", cputime());
  45. Bflush(&bso);
  46. c = INITTEXT;
  47. for(p = firstp; p != P; p = p->link) {
  48. if(p->as == ATEXT)
  49. curtext = p;
  50. o = &optab[p->as];
  51. p->pc = c;
  52. m = mmsize[o->optype];
  53. if(m == 0) {
  54. if(p->as == AWORD)
  55. m = 2;
  56. if(p->as == ALONG)
  57. m = 4;
  58. p->mark = m;
  59. c += m;
  60. continue;
  61. }
  62. if(p->from.type != D_NONE)
  63. m += andsize(p, &p->from);
  64. if(p->to.type == D_BRANCH) {
  65. if(p->pcond == P)
  66. p->pcond = p;
  67. c += m;
  68. if(m == 2)
  69. m |= 0100;
  70. p->mark = m;
  71. continue;
  72. }
  73. if(p->to.type != D_NONE)
  74. m += andsize(p, &p->to);
  75. p->mark = m;
  76. c += m;
  77. }
  78. loop:
  79. n++;
  80. if(debug['v'])
  81. Bprint(&bso, "%5.2f span %d\n", cputime(), n);
  82. Bflush(&bso);
  83. if(n > 60) {
  84. diag("span must be looping");
  85. errorexit();
  86. }
  87. c = INITTEXT;
  88. for(p = firstp; p != P; p = p->link) {
  89. if(p->as == ATEXT)
  90. curtext = p;
  91. if((m = p->mark) & 0100) {
  92. q = p->pcond;
  93. v = q->pc - 2;
  94. if(p->back)
  95. v -= c;
  96. else
  97. v -= p->pc;
  98. p->pc = c;
  99. if(v < -32768L || v >= 32768L) {
  100. c += 6; /* only jsr and jmp can do this */
  101. } else
  102. if(v < -128 || v >= 128)
  103. c += 4;
  104. else
  105. if(v == 0) {
  106. c += 4;
  107. p->mark = 4;
  108. } else
  109. c += 2;
  110. continue;
  111. }
  112. p->pc = c;
  113. c += m;
  114. }
  115. if(c != textsize) {
  116. textsize = c;
  117. goto loop;
  118. }
  119. if(INITRND)
  120. INITDAT = rnd(c, INITRND);
  121. if(INITDAT != idat) {
  122. idat = INITDAT;
  123. goto start;
  124. }
  125. xdefine("etext", STEXT, c);
  126. xdefine("a6base", STEXT, INITDAT+A6OFFSET);
  127. if(debug['v'])
  128. Bprint(&bso, "etext = %lux\n", c);
  129. Bflush(&bso);
  130. for(p = textp; p != P; p = p->pcond)
  131. p->from.sym->value = p->pc;
  132. textsize = c - INITTEXT;
  133. }
  134. void
  135. xdefine(char *p, int t, long v)
  136. {
  137. Sym *s;
  138. s = lookup(p, 0);
  139. if(s->type == 0 || s->type == SXREF) {
  140. s->type = t;
  141. s->value = v;
  142. }
  143. if(s->type == STEXT && s->value == 0)
  144. s->value = v;
  145. }
  146. int
  147. andsize(Prog *p, Adr *ap)
  148. {
  149. int t, n;
  150. long v;
  151. Optab *o;
  152. t = ap->type;
  153. n = simple[t];
  154. if(n != 0177) {
  155. v = ap->offset;
  156. if(v == 0)
  157. return 0;
  158. if((n&070) != 020) /* D_INDIR */
  159. return 0;
  160. if(v == 0)
  161. return 0;
  162. return 2;
  163. }
  164. if((t&I_MASK) == I_ADDR)
  165. t = D_CONST;
  166. switch(t) {
  167. default:
  168. return 0;
  169. case D_STACK:
  170. case D_AUTO:
  171. case D_PARAM:
  172. v = ap->offset;
  173. if(v == 0)
  174. return 0;
  175. return 2;
  176. case I_INDIR|D_CONST:
  177. v = ap->offset;
  178. if(v < -32768L || v >= 32768L)
  179. return 4;
  180. return 2;
  181. case D_STATIC:
  182. case D_EXTERN:
  183. if(ap->sym->type == STEXT) {
  184. if(HEADTYPE == 4)
  185. return 2;
  186. return 4;
  187. }
  188. v = ap->sym->value + ap->offset - A6OFFSET;
  189. if(v == 0)
  190. return 0;
  191. if(v < -32768L || v >= 32768L)
  192. return 4;
  193. return 2;
  194. case D_CONST:
  195. case D_FCONST:
  196. o = &optab[p->as];
  197. if(ap == &(p->from))
  198. return o->srcsp;
  199. return o->dstsp;
  200. case D_CCR:
  201. case D_SR:
  202. if(p->as == AMOVW)
  203. return 0;
  204. return 2;
  205. case D_USP:
  206. t = p->from.type;
  207. if(t >= D_A0 && t <= D_A0+8)
  208. return 0;
  209. t = p->to.type;
  210. if(t >= D_A0 && t <= D_A0+8)
  211. return 0;
  212. case D_SFC:
  213. case D_DFC:
  214. case D_CACR:
  215. case D_VBR:
  216. case D_CAAR:
  217. case D_MSP:
  218. case D_ISP:
  219. case D_FPCR:
  220. case D_FPSR:
  221. case D_FPIAR:
  222. case D_TC:
  223. case D_ITT0:
  224. case D_ITT1:
  225. case D_DTT0:
  226. case D_DTT1:
  227. case D_MMUSR:
  228. case D_URP:
  229. case D_SRP:
  230. return 2;
  231. }
  232. }
  233. void
  234. putsymb(Sym *s, int t, long v)
  235. {
  236. int i, f;
  237. char *n;
  238. n = s->name;
  239. if(t == 'f')
  240. n++;
  241. lput(v);
  242. if(s->version)
  243. t += 'a' - 'A';
  244. CPUT(t+0x80); /* 0x80 is variable length */
  245. if(t == 'Z' || t == 'z') {
  246. CPUT(n[0]);
  247. for(i=1; n[i] != 0 || n[i+1] != 0; i += 2) {
  248. CPUT(n[i]);
  249. CPUT(n[i+1]);
  250. }
  251. CPUT(0);
  252. CPUT(0);
  253. i++;
  254. }
  255. else {
  256. for(i=0; n[i]; i++)
  257. CPUT(n[i]);
  258. CPUT(0);
  259. }
  260. symsize += 4 + 1 + i + 1;
  261. if(debug['n']) {
  262. if(t == 'z' || t == 'Z') {
  263. Bprint(&bso, "%c %.8lux ", t, v);
  264. for(i=1; n[i] != 0 || n[i+1] != 0; i+=2) {
  265. f = ((n[i]&0xff) << 8) | (n[i+1]&0xff);
  266. Bprint(&bso, "/%x", f);
  267. }
  268. Bprint(&bso, "\n");
  269. return;
  270. }
  271. if(s->version)
  272. Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, n, s->version);
  273. else
  274. Bprint(&bso, "%c %.8lux %s\n", t, v, n);
  275. }
  276. }
  277. void
  278. asmsym(void)
  279. {
  280. Prog *p;
  281. Auto *a;
  282. Sym *s;
  283. int h;
  284. s = lookup("etext", 0);
  285. if(s->type == STEXT)
  286. putsymb(s, 'T', s->value);
  287. s = lookup("a6base", 0);
  288. if(s->type == STEXT)
  289. putsymb(s, 'D', s->value);
  290. for(h=0; h<NHASH; h++)
  291. for(s=hash[h]; s!=S; s=s->link)
  292. switch(s->type) {
  293. case SDATA:
  294. putsymb(s, 'D', s->value+INITDAT);
  295. continue;
  296. case SBSS:
  297. putsymb(s, 'B', s->value+INITDAT);
  298. continue;
  299. case SFILE:
  300. putsymb(s, 'f', s->value);
  301. continue;
  302. }
  303. for(p=textp; p!=P; p=p->pcond) {
  304. s = p->from.sym;
  305. if(s->type != STEXT)
  306. continue;
  307. /* filenames first */
  308. for(a=p->to.autom; a; a=a->link)
  309. if(a->type == D_FILE)
  310. putsymb(a->asym, 'z', a->aoffset);
  311. else
  312. if(a->type == D_FILE1)
  313. putsymb(a->asym, 'Z', a->aoffset);
  314. putsymb(s, 'T', s->value);
  315. /* auto and param after */
  316. for(a=p->to.autom; a; a=a->link)
  317. if(a->type == D_AUTO)
  318. putsymb(a->asym, 'a', -a->aoffset);
  319. else
  320. if(a->type == D_PARAM)
  321. putsymb(a->asym, 'p', a->aoffset);
  322. }
  323. if(debug['v'] || debug['n'])
  324. Bprint(&bso, "symsize = %lud\n", symsize);
  325. Bflush(&bso);
  326. }
  327. #define MINLC 2
  328. void
  329. asmsp(void)
  330. {
  331. long oldpc, oldsp;
  332. Prog *p;
  333. int s;
  334. long v;
  335. oldpc = INITTEXT;
  336. oldsp = 0;
  337. for(p = firstp; p != P; p = p->link) {
  338. if(p->stkoff == oldsp || p->as == ATEXT || p->as == ANOP) {
  339. if(p->as == ATEXT)
  340. curtext = p;
  341. if(debug['G'])
  342. Bprint(&bso, "%6lux %4ld%P\n",
  343. p->pc, p->stkoff, p);
  344. continue;
  345. }
  346. if(debug['G'])
  347. Bprint(&bso, "\t\t%6ld", spsize);
  348. v = (p->pc - oldpc) / MINLC;
  349. while(v) {
  350. s = 127;
  351. if(v < 127)
  352. s = v;
  353. CPUT(s+128); /* 129-255 +pc */
  354. if(debug['G'])
  355. Bprint(&bso, " pc+%d*2(%d)", s, s+128);
  356. v -= s;
  357. spsize++;
  358. }
  359. v = p->stkoff - oldsp;
  360. oldsp = p->stkoff;
  361. oldpc = p->pc + MINLC;
  362. if(v & 3 || v > 64L*4L || v < -64L*4L) {
  363. CPUT(0); /* 0 vvvv +sp */
  364. lput(v);
  365. if(debug['G']) {
  366. if(v > 0)
  367. Bprint(&bso, " sp+%ld*1(%d,%ld)\n",
  368. v, 0, v);
  369. else
  370. Bprint(&bso, " sp%ld*1(%d,%ld)\n",
  371. v, 0, v);
  372. Bprint(&bso, "%6lux %4ld%P\n",
  373. p->pc, p->stkoff, p);
  374. }
  375. spsize += 5;
  376. continue;
  377. }
  378. s = v/4;
  379. if(s > 0) {
  380. CPUT(0+s); /* 1-64 +sp */
  381. if(debug['G']) {
  382. Bprint(&bso, " sp+%d*4(%d)\n", s, 0+s);
  383. Bprint(&bso, "%6lux %4ld%P\n",
  384. p->pc, p->stkoff, p);
  385. }
  386. } else {
  387. CPUT(64-s); /* 65-128 -sp */
  388. if(debug['G']) {
  389. Bprint(&bso, " sp%d*4(%d)\n", s, 64-s);
  390. Bprint(&bso, "%6lux %4ld%P\n",
  391. p->pc, p->stkoff, p);
  392. }
  393. }
  394. spsize++;
  395. }
  396. while(spsize & 1) {
  397. s = 129;
  398. CPUT(s);
  399. spsize++;
  400. }
  401. if(debug['v'] || debug['G'])
  402. Bprint(&bso, "stsize = %ld\n", spsize);
  403. Bflush(&bso);
  404. }
  405. void
  406. asmlc(void)
  407. {
  408. long oldpc, oldlc;
  409. Prog *p;
  410. long v, s;
  411. oldpc = INITTEXT;
  412. oldlc = 0;
  413. for(p = firstp; p != P; p = p->link) {
  414. if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
  415. if(p->as == ATEXT)
  416. curtext = p;
  417. if(debug['L'])
  418. Bprint(&bso, "%6lux %P\n",
  419. p->pc, p);
  420. continue;
  421. }
  422. if(debug['L'])
  423. Bprint(&bso, "\t\t%6ld", lcsize);
  424. v = (p->pc - oldpc) / MINLC;
  425. while(v) {
  426. s = 127;
  427. if(v < 127)
  428. s = v;
  429. CPUT(s+128); /* 129-255 +pc */
  430. if(debug['L'])
  431. Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
  432. v -= s;
  433. lcsize++;
  434. }
  435. s = p->line - oldlc;
  436. oldlc = p->line;
  437. oldpc = p->pc + MINLC;
  438. if(s > 64 || s < -64) {
  439. CPUT(0); /* 0 vv +lc */
  440. CPUT(s>>24);
  441. CPUT(s>>16);
  442. CPUT(s>>8);
  443. CPUT(s);
  444. if(debug['L']) {
  445. if(s > 0)
  446. Bprint(&bso, " lc+%ld(%d,%ld)\n",
  447. s, 0, s);
  448. else
  449. Bprint(&bso, " lc%ld(%d,%ld)\n",
  450. s, 0, s);
  451. Bprint(&bso, "%6lux %P\n",
  452. p->pc, p);
  453. }
  454. lcsize += 5;
  455. continue;
  456. }
  457. if(s > 0) {
  458. CPUT(0+s); /* 1-64 +lc */
  459. if(debug['L']) {
  460. Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
  461. Bprint(&bso, "%6lux %P\n",
  462. p->pc, p);
  463. }
  464. } else {
  465. CPUT(64-s); /* 65-128 -lc */
  466. if(debug['L']) {
  467. Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
  468. Bprint(&bso, "%6lux %P\n",
  469. p->pc, p);
  470. }
  471. }
  472. lcsize++;
  473. }
  474. while(lcsize & 1) {
  475. s = 129;
  476. CPUT(s);
  477. lcsize++;
  478. }
  479. if(debug['v'] || debug['L'])
  480. Bprint(&bso, "lcsize = %ld\n", lcsize);
  481. Bflush(&bso);
  482. }