span.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551
  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. if(p->as == ABSR && q->pc < 32768L && q->pc >= 0)
  101. c += 4;
  102. else
  103. c += 6;
  104. } else
  105. if(v < -128 || v >= 128)
  106. c += 4;
  107. else
  108. if(v == 0) {
  109. c += 4;
  110. p->mark = 4;
  111. } else
  112. c += 2;
  113. continue;
  114. }
  115. p->pc = c;
  116. c += m;
  117. }
  118. if(c != textsize) {
  119. textsize = c;
  120. goto loop;
  121. }
  122. if(INITRND)
  123. INITDAT = rnd(c, INITRND);
  124. if(INITDAT != idat) {
  125. idat = INITDAT;
  126. goto start;
  127. }
  128. xdefine("etext", STEXT, c);
  129. xdefine("a6base", STEXT, INITDAT+A6OFFSET);
  130. if(debug['v'])
  131. Bprint(&bso, "etext = %lux\n", c);
  132. Bflush(&bso);
  133. for(p = textp; p != P; p = p->pcond)
  134. p->from.sym->value = p->pc;
  135. textsize = c - INITTEXT;
  136. }
  137. void
  138. xdefine(char *p, int t, long v)
  139. {
  140. Sym *s;
  141. s = lookup(p, 0);
  142. if(s->type == 0 || s->type == SXREF) {
  143. s->type = t;
  144. s->value = v;
  145. }
  146. if(s->type == STEXT && s->value == 0)
  147. s->value = v;
  148. }
  149. int
  150. andsize(Prog *p, Adr *ap)
  151. {
  152. int t, n;
  153. long v;
  154. Optab *o;
  155. t = ap->type;
  156. if(ap->index != D_NONE) {
  157. n = 2;
  158. v = ap->displace;
  159. if(v != 0) {
  160. n += 2;
  161. if(v < -32768L || v >= 32768L)
  162. n += 2;
  163. }
  164. switch(t) {
  165. default:
  166. v = ap->offset;
  167. break;
  168. case D_STATIC:
  169. case D_EXTERN:
  170. if(ap->sym->type == STEXT)
  171. return n+4; /* see below */
  172. v = ap->sym->value + ap->offset - A6OFFSET;
  173. if(debug['6'])
  174. v += INITDAT + A6OFFSET;
  175. }
  176. if(v != 0) {
  177. n += 2;
  178. if(v < -32768L || v >= 32768L)
  179. n += 2;
  180. }
  181. return n;
  182. }
  183. n = simple[t];
  184. if(n != 0177) {
  185. v = ap->offset;
  186. if(v == 0)
  187. return 0;
  188. if((n&070) != 020) /* D_INDIR */
  189. return 0;
  190. if(v == 0)
  191. return 0;
  192. if(v < -32768L || v >= 32768L)
  193. return 6; /* switch to index1 mode */
  194. return 2;
  195. }
  196. if((t&I_MASK) == I_ADDR)
  197. t = D_CONST;
  198. switch(t) {
  199. default:
  200. return 0;
  201. case D_STACK:
  202. case D_AUTO:
  203. case D_PARAM:
  204. v = ap->offset;
  205. if(v == 0)
  206. return 0;
  207. if(v < -32768L || v >= 32768L)
  208. return 6; /* switch to index1 mode */
  209. return 2;
  210. case I_INDIR|D_CONST:
  211. v = ap->offset;
  212. goto adr;
  213. case D_STATIC:
  214. case D_EXTERN:
  215. if(ap->sym->type == STEXT)
  216. return 4; /* too slow to get back into namelist */
  217. v = ap->sym->value + ap->offset - A6OFFSET;
  218. if(debug['6']) {
  219. v += INITDAT + A6OFFSET;
  220. goto adr;
  221. }
  222. if(v == 0)
  223. return 0;
  224. adr:
  225. if(v < -32768L || v >= 32768L)
  226. return 4;
  227. return 2;
  228. case D_CONST:
  229. case D_FCONST:
  230. o = &optab[p->as];
  231. if(ap == &(p->from))
  232. return o->srcsp;
  233. return o->dstsp;
  234. case D_CCR:
  235. case D_SR:
  236. if(p->as == AMOVW)
  237. return 0;
  238. return 2;
  239. case D_USP:
  240. t = p->from.type;
  241. if(t >= D_A0 && t <= D_A0+8)
  242. return 0;
  243. t = p->to.type;
  244. if(t >= D_A0 && t <= D_A0+8)
  245. return 0;
  246. case D_SFC:
  247. case D_DFC:
  248. case D_CACR:
  249. case D_VBR:
  250. case D_CAAR:
  251. case D_MSP:
  252. case D_ISP:
  253. case D_FPCR:
  254. case D_FPSR:
  255. case D_FPIAR:
  256. case D_TC:
  257. case D_ITT0:
  258. case D_ITT1:
  259. case D_DTT0:
  260. case D_DTT1:
  261. case D_MMUSR:
  262. case D_URP:
  263. case D_SRP:
  264. return 2;
  265. }
  266. }
  267. void
  268. putsymb(Sym *s, int t, long v)
  269. {
  270. int i, f;
  271. char *n;
  272. n = s->name;
  273. if(t == 'f')
  274. n++;
  275. lput(v);
  276. if(s->version)
  277. t += 'a' - 'A';
  278. CPUT(t+0x80); /* 0x80 is variable length */
  279. if(t == 'Z' || t == 'z') {
  280. CPUT(n[0]);
  281. for(i=1; n[i] != 0 || n[i+1] != 0; i += 2) {
  282. CPUT(n[i]);
  283. CPUT(n[i+1]);
  284. }
  285. CPUT(0);
  286. CPUT(0);
  287. i++;
  288. }
  289. else {
  290. for(i=0; n[i]; i++)
  291. CPUT(n[i]);
  292. CPUT(0);
  293. }
  294. symsize += 4 + 1 + i + 1;
  295. if(debug['n']) {
  296. if(t == 'z' || t == 'Z') {
  297. Bprint(&bso, "%c %.8lux ", t, v);
  298. for(i=1; n[i] != 0 || n[i+1] != 0; i+=2) {
  299. f = ((n[i]&0xff) << 8) | (n[i+1]&0xff);
  300. Bprint(&bso, "/%x", f);
  301. }
  302. Bprint(&bso, "\n");
  303. return;
  304. }
  305. if(s->version)
  306. Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, n, s->version);
  307. else
  308. Bprint(&bso, "%c %.8lux %s\n", t, v, n);
  309. }
  310. }
  311. void
  312. asmsym(void)
  313. {
  314. Prog *p;
  315. Auto *a;
  316. Sym *s;
  317. int h;
  318. s = lookup("etext", 0);
  319. if(s->type == STEXT)
  320. putsymb(s, 'T', s->value);
  321. s = lookup("a6base", 0);
  322. if(s->type == STEXT)
  323. putsymb(s, 'D', s->value);
  324. for(h=0; h<NHASH; h++)
  325. for(s=hash[h]; s!=S; s=s->link)
  326. switch(s->type) {
  327. case SDATA:
  328. putsymb(s, 'D', s->value+INITDAT);
  329. continue;
  330. case SBSS:
  331. putsymb(s, 'B', s->value+INITDAT);
  332. continue;
  333. case SFILE:
  334. putsymb(s, 'f', s->value);
  335. continue;
  336. }
  337. for(p=textp; p!=P; p=p->pcond) {
  338. s = p->from.sym;
  339. if(s->type != STEXT)
  340. continue;
  341. /* filenames first */
  342. for(a=p->to.autom; a; a=a->link)
  343. if(a->type == D_FILE)
  344. putsymb(a->asym, 'z', a->aoffset);
  345. else
  346. if(a->type == D_FILE1)
  347. putsymb(a->asym, 'Z', a->aoffset);
  348. putsymb(s, 'T', s->value);
  349. /* auto and param after */
  350. for(a=p->to.autom; a; a=a->link)
  351. if(a->type == D_AUTO)
  352. putsymb(a->asym, 'a', -a->aoffset);
  353. else
  354. if(a->type == D_PARAM)
  355. putsymb(a->asym, 'p', a->aoffset);
  356. }
  357. if(debug['v'] || debug['n'])
  358. Bprint(&bso, "symsize = %lud\n", symsize);
  359. Bflush(&bso);
  360. }
  361. #define MINLC 2
  362. void
  363. asmsp(void)
  364. {
  365. long oldpc, oldsp;
  366. Prog *p;
  367. int s;
  368. long v;
  369. oldpc = INITTEXT;
  370. oldsp = 0;
  371. for(p = firstp; p != P; p = p->link) {
  372. if(p->stkoff == oldsp || p->as == ATEXT || p->as == ANOP) {
  373. if(p->as == ATEXT)
  374. curtext = p;
  375. if(debug['G'])
  376. Bprint(&bso, "%6lux %4ld%P\n",
  377. p->pc, p->stkoff, p);
  378. continue;
  379. }
  380. if(debug['G'])
  381. Bprint(&bso, "\t\t%6ld", spsize);
  382. v = (p->pc - oldpc) / MINLC;
  383. while(v) {
  384. s = 127;
  385. if(v < 127)
  386. s = v;
  387. CPUT(s+128); /* 129-255 +pc */
  388. if(debug['G'])
  389. Bprint(&bso, " pc+%d*2(%d)", s, s+128);
  390. v -= s;
  391. spsize++;
  392. }
  393. v = p->stkoff - oldsp;
  394. oldsp = p->stkoff;
  395. oldpc = p->pc + MINLC;
  396. if(v & 3 || v > 64L*4L || v < -64L*4L) {
  397. CPUT(0); /* 0 vvvv +sp */
  398. lput(v);
  399. if(debug['G']) {
  400. if(v > 0)
  401. Bprint(&bso, " sp+%ld*1(%d,%ld)\n",
  402. v, 0, v);
  403. else
  404. Bprint(&bso, " sp%ld*1(%d,%ld)\n",
  405. v, 0, v);
  406. Bprint(&bso, "%6lux %4ld%P\n",
  407. p->pc, p->stkoff, p);
  408. }
  409. spsize += 5;
  410. continue;
  411. }
  412. s = v/4;
  413. if(s > 0) {
  414. CPUT(0+s); /* 1-64 +sp */
  415. if(debug['G']) {
  416. Bprint(&bso, " sp+%d*4(%d)\n", s, 0+s);
  417. Bprint(&bso, "%6lux %4ld%P\n",
  418. p->pc, p->stkoff, p);
  419. }
  420. } else {
  421. CPUT(64-s); /* 65-128 -sp */
  422. if(debug['G']) {
  423. Bprint(&bso, " sp%d*4(%d)\n", s, 64-s);
  424. Bprint(&bso, "%6lux %4ld%P\n",
  425. p->pc, p->stkoff, p);
  426. }
  427. }
  428. spsize++;
  429. }
  430. while(spsize & 1) {
  431. s = 129;
  432. CPUT(s);
  433. spsize++;
  434. }
  435. if(debug['v'] || debug['G'])
  436. Bprint(&bso, "stsize = %ld\n", spsize);
  437. Bflush(&bso);
  438. }
  439. void
  440. asmlc(void)
  441. {
  442. long oldpc, oldlc;
  443. Prog *p;
  444. long v, s;
  445. oldpc = INITTEXT;
  446. oldlc = 0;
  447. for(p = firstp; p != P; p = p->link) {
  448. if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
  449. if(p->as == ATEXT)
  450. curtext = p;
  451. if(debug['L'])
  452. Bprint(&bso, "%6lux %P\n",
  453. p->pc, p);
  454. continue;
  455. }
  456. if(debug['L'])
  457. Bprint(&bso, "\t\t%6ld", lcsize);
  458. v = (p->pc - oldpc) / MINLC;
  459. while(v) {
  460. s = 127;
  461. if(v < 127)
  462. s = v;
  463. CPUT(s+128); /* 129-255 +pc */
  464. if(debug['L'])
  465. Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
  466. v -= s;
  467. lcsize++;
  468. }
  469. s = p->line - oldlc;
  470. oldlc = p->line;
  471. oldpc = p->pc + MINLC;
  472. if(s > 64 || s < -64) {
  473. CPUT(0); /* 0 vv +lc */
  474. CPUT(s>>24);
  475. CPUT(s>>16);
  476. CPUT(s>>8);
  477. CPUT(s);
  478. if(debug['L']) {
  479. if(s > 0)
  480. Bprint(&bso, " lc+%ld(%d,%ld)\n",
  481. s, 0, s);
  482. else
  483. Bprint(&bso, " lc%ld(%d,%ld)\n",
  484. s, 0, s);
  485. Bprint(&bso, "%6lux %P\n",
  486. p->pc, p);
  487. }
  488. lcsize += 5;
  489. continue;
  490. }
  491. if(s > 0) {
  492. CPUT(0+s); /* 1-64 +lc */
  493. if(debug['L']) {
  494. Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
  495. Bprint(&bso, "%6lux %P\n",
  496. p->pc, p);
  497. }
  498. } else {
  499. CPUT(64-s); /* 65-128 -lc */
  500. if(debug['L']) {
  501. Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
  502. Bprint(&bso, "%6lux %P\n",
  503. p->pc, p);
  504. }
  505. }
  506. lcsize++;
  507. }
  508. while(lcsize & 1) {
  509. s = 129;
  510. CPUT(s);
  511. lcsize++;
  512. }
  513. if(debug['v'] || debug['L'])
  514. Bprint(&bso, "lcsize = %ld\n", lcsize);
  515. Bflush(&bso);
  516. }