span.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. #include "l.h"
  2. #define BIG ((1<<17)-10)
  3. void
  4. span(void)
  5. {
  6. Prog *p;
  7. Sym *setext;
  8. Optab *o;
  9. int m;
  10. long c, oc, v;
  11. oc = 0;
  12. loop:
  13. if(debug['v'])
  14. Bprint(&bso, "%5.2f span\n", cputime());
  15. Bflush(&bso);
  16. c = INITTEXT;
  17. for(p = firstp; p != P; p = p->link) {
  18. if(oc != 0 && p->to.type == D_BRANCH && p->to.class == C_SBRA+1) {
  19. v = 0;
  20. if(p->cond != P)
  21. if(p->cond->pc > c)
  22. v = p->cond->pc - p->pc; /* foreward */
  23. else
  24. v = p->cond->pc - c; /* backward */
  25. if(v < -BIG || v > BIG) {
  26. p->to.class = C_LBRA+1;
  27. p->optab = 0;
  28. }
  29. }
  30. p->pc = c;
  31. o = oplook(p);
  32. m = o->size;
  33. if(m == 0) {
  34. if(p->as == ATEXT) {
  35. curtext = p;
  36. autosize = p->to.offset + 4;
  37. if(p->from.sym != S)
  38. p->from.sym->value = c;
  39. continue;
  40. }
  41. diag("zero-width instruction\n%P\n", p);
  42. continue;
  43. }
  44. c += m;
  45. }
  46. c = rnd(c, 8);
  47. setext = lookup("etext", 0);
  48. if(setext != S) {
  49. setext->value = c;
  50. textsize = c - INITTEXT;
  51. }
  52. if(INITRND)
  53. INITDAT = rnd(c, INITRND);
  54. if(debug['v'])
  55. Bprint(&bso, "tsize = %lux\n", textsize);
  56. if(oc != c) {
  57. oc = c;
  58. goto loop;
  59. }
  60. Bflush(&bso);
  61. }
  62. void
  63. xdefine(char *p, int t, long v)
  64. {
  65. Sym *s;
  66. s = lookup(p, 0);
  67. if(s->type == 0 || s->type == SXREF) {
  68. s->type = t;
  69. s->value = v;
  70. }
  71. }
  72. long
  73. regoff(Adr *a)
  74. {
  75. offset = 0;
  76. aclass(a);
  77. return offset;
  78. }
  79. int
  80. cclass(void)
  81. {
  82. long o;
  83. o = offset;
  84. if(o == 0)
  85. return C_ZCON-C_ZCON;
  86. if((o & ~0xff) == 0)
  87. return C_SCON-C_ZCON;
  88. if((o & ~0xff) == ~0xff)
  89. return C_MCON-C_ZCON;
  90. if((o & ~0xffff) == 0)
  91. return C_PCON-C_ZCON;
  92. if((o & ~0xffff) == ~0xffff)
  93. return C_NCON-C_ZCON;
  94. return C_LCON-C_ZCON;
  95. }
  96. int
  97. aclass(Adr *a)
  98. {
  99. Sym *s;
  100. int t;
  101. noacache = 0;
  102. switch(a->type) {
  103. case D_NONE:
  104. return C_NONE;
  105. case D_REG:
  106. return C_REG;
  107. case D_OREG:
  108. switch(a->name) {
  109. case D_EXTERN:
  110. case D_STATIC:
  111. if(a->sym == 0 || a->sym->name == 0) {
  112. print("null sym external\n");
  113. print("%D\n", a);
  114. return C_GOK;
  115. }
  116. t = a->sym->type;
  117. if(t == 0 || t == SXREF) {
  118. diag("undefined external: %s in %s\n",
  119. a->sym->name, TNAME);
  120. a->sym->type = SDATA;
  121. }
  122. offset = a->sym->value + a->offset + INITDAT;
  123. noacache = 1;
  124. if(offset >= INITDAT && offset <= INITDAT+0xff+0xff)
  125. return C_SEXT;
  126. if(offset >= 0 && offset <= 0xffff)
  127. return C_SEXT;
  128. return C_LEXT;
  129. case D_AUTO:
  130. offset = autosize + a->offset;
  131. return C_ZAUTO + cclass();
  132. case D_PARAM:
  133. offset = autosize + a->offset + 4L;
  134. return C_ZAUTO + cclass();
  135. case D_NONE:
  136. offset = a->offset;
  137. t = C_ZOREG + cclass();
  138. if(a->reg == NREG) {
  139. if(t == C_LOREG)
  140. return C_LEXT;
  141. /*
  142. if(t == C_POREG)
  143. return C_SEXT;
  144. */
  145. }
  146. return t;
  147. }
  148. return C_GOK;
  149. case D_OCONST:
  150. switch(a->name) {
  151. case D_EXTERN:
  152. case D_STATIC:
  153. s = a->sym;
  154. t = s->type;
  155. if(t == 0 || t == SXREF) {
  156. diag("undefined external: %s in %s\n",
  157. s->name, TNAME);
  158. s->type = SDATA;
  159. }
  160. offset = s->value + a->offset;
  161. if(s->type != STEXT && s->type != SLEAF) {
  162. noacache = 1;
  163. offset += INITDAT;
  164. }
  165. return C_ZCON + cclass();
  166. }
  167. return C_GOK;
  168. case D_CONST:
  169. switch(a->name) {
  170. case D_NONE:
  171. offset = a->offset;
  172. if(a->reg != NREG)
  173. return C_ZACON + cclass();
  174. return C_ZCON + cclass();
  175. case D_EXTERN:
  176. case D_STATIC:
  177. s = a->sym;
  178. if(s == S)
  179. break;
  180. t = s->type;
  181. switch(t) {
  182. case 0:
  183. case SXREF:
  184. diag("undefined external: %s in %s\n",
  185. s->name, TNAME);
  186. s->type = SDATA;
  187. break;
  188. case STEXT:
  189. case SLEAF:
  190. offset = s->value + a->offset;
  191. return C_LCON;
  192. }
  193. offset = s->value + a->offset + INITDAT;
  194. noacache = 1;
  195. return C_ZCON + cclass();
  196. case D_AUTO:
  197. offset = autosize + a->offset;
  198. return C_ZACON + cclass();
  199. case D_PARAM:
  200. offset = autosize + a->offset + 4L;
  201. return C_ZACON + cclass();
  202. }
  203. return C_GOK;
  204. case D_BRANCH:
  205. return C_SBRA;
  206. }
  207. return C_GOK;
  208. }
  209. Optab*
  210. oplook(Prog *p)
  211. {
  212. int a1, a2, a3, r, noopcache;
  213. char *c1, *c3;
  214. Optab *o, *e;
  215. a1 = p->optab;
  216. if(a1)
  217. return optab+(a1-1);
  218. noopcache = 0;
  219. a1 = p->from.class;
  220. if(a1 == 0) {
  221. a1 = aclass(&p->from) + 1;
  222. if(!noacache)
  223. p->from.class = a1;
  224. else
  225. noopcache = 1;
  226. }
  227. a1--;
  228. a3 = p->to.class;
  229. if(a3 == 0) {
  230. a3 = aclass(&p->to) + 1;
  231. if(!noacache)
  232. p->to.class = a3;
  233. else
  234. noopcache = 1;
  235. }
  236. a3--;
  237. a2 = C_NONE;
  238. if(p->reg != NREG)
  239. a2 = C_REG;
  240. r = p->as;
  241. o = oprange[r].start;
  242. if(o == 0) {
  243. r = opcross[repop[r]][a1][a2][a3];
  244. if(r) {
  245. if(!noopcache)
  246. p->optab = r;
  247. return optab+r-1;
  248. }
  249. diag("no combination %A %d %d %d\n%P\n",
  250. p->as, a1, a2, a3, p);
  251. return optab + opcross[repop[AMOVL]][C_REG][C_NONE][C_REG] - 1;
  252. }
  253. e = oprange[r].stop;
  254. c1 = xcmp[a1];
  255. c3 = xcmp[a3];
  256. for(; o<e; o++)
  257. if(o->a2 == a2)
  258. if(c1[o->a1])
  259. if(c3[o->a3]) {
  260. if(!noopcache)
  261. p->optab = (o-optab)+1;
  262. return o;
  263. }
  264. diag("illegal combination %A %d %d %d\n%P\n",
  265. p->as, a1, a2, a3, p);
  266. return o;
  267. }
  268. int
  269. cmp(int a, int b)
  270. {
  271. if(a == b)
  272. return 1;
  273. switch(a) {
  274. case C_LCON:
  275. if(b == C_ZCON || b == C_SCON || b == C_MCON ||
  276. b == C_PCON || b == C_NCON)
  277. return 1;
  278. break;
  279. case C_PCON:
  280. if(b == C_ZCON || b == C_SCON)
  281. return 1;
  282. break;
  283. case C_SCON:
  284. if(b == C_ZCON)
  285. return 1;
  286. break;
  287. case C_NCON:
  288. if(b == C_MCON)
  289. return 1;
  290. break;
  291. case C_LACON:
  292. if(b == C_ZACON || b == C_SACON || b == C_MACON ||
  293. b == C_PACON || b == C_NACON)
  294. return 1;
  295. break;
  296. case C_PACON:
  297. if(b == C_ZACON || b == C_SACON)
  298. return 1;
  299. break;
  300. case C_SACON:
  301. if(b == C_ZACON)
  302. return 1;
  303. break;
  304. case C_NACON:
  305. if(b == C_MACON)
  306. return 1;
  307. break;
  308. case C_LBRA:
  309. if(b == C_SBRA)
  310. return 1;
  311. break;
  312. case C_LAUTO:
  313. if(b == C_ZAUTO || b == C_SAUTO || b == C_MAUTO ||
  314. b == C_PAUTO || b == C_NAUTO)
  315. return 1;
  316. break;
  317. case C_PAUTO:
  318. if(b == C_ZAUTO || b == C_SAUTO)
  319. return 1;
  320. break;
  321. case C_SAUTO:
  322. if(b == C_ZAUTO)
  323. return 1;
  324. break;
  325. case C_NAUTO:
  326. if(b == C_MAUTO)
  327. return 1;
  328. break;
  329. case C_LOREG:
  330. if(b == C_ZOREG || b == C_SOREG || b == C_MOREG ||
  331. b == C_POREG || b == C_NOREG)
  332. return 1;
  333. break;
  334. case C_POREG:
  335. if(b == C_ZOREG || b == C_SOREG)
  336. return 1;
  337. break;
  338. case C_SOREG:
  339. if(b == C_ZOREG)
  340. return 1;
  341. break;
  342. case C_NOREG:
  343. if(b == C_MOREG)
  344. return 1;
  345. break;
  346. case C_LEXT:
  347. if(b == C_SEXT)
  348. return 1;
  349. break;
  350. }
  351. return 0;
  352. }
  353. int
  354. ocmp(void *a1, void *a2)
  355. {
  356. Optab *p1, *p2;
  357. int n;
  358. p1 = a1;
  359. p2 = a2;
  360. n = p1->as - p2->as;
  361. if(n)
  362. return n;
  363. n = p1->a1 - p2->a1;
  364. if(n)
  365. return n;
  366. n = p1->a2 - p2->a2;
  367. if(n)
  368. return n;
  369. n = p1->a3 - p2->a3;
  370. if(n)
  371. return n;
  372. return 0;
  373. }
  374. void
  375. buildop(void)
  376. {
  377. int i, n, r;
  378. for(i=0; i<32; i++)
  379. for(n=0; n<32; n++)
  380. xcmp[i][n] = cmp(n, i);
  381. for(n=0; optab[n].as != AXXX; n++)
  382. ;
  383. qsort(optab, n, sizeof(optab[0]), ocmp);
  384. for(i=0; i<n; i++) {
  385. r = optab[i].as;
  386. oprange[r].start = optab+i;
  387. while(optab[i].as == r)
  388. i++;
  389. oprange[r].stop = optab+i;
  390. i--;
  391. switch(r)
  392. {
  393. default:
  394. diag("unknown op in build: %A\n", r);
  395. errorexit();
  396. case AMOVL:
  397. buildrep(1, r);
  398. oprange[AMOVH] = oprange[r];
  399. repop[AMOVH] = 1;
  400. oprange[AMOVHU] = oprange[r];
  401. repop[AMOVHU] = 1;
  402. oprange[AMOVB] = oprange[r];
  403. repop[AMOVB] = 1;
  404. oprange[AMOVBU] = oprange[r];
  405. repop[AMOVBU] = 1;
  406. oprange[ALOADSET] = oprange[r];
  407. repop[ALOADSET] = 1;
  408. oprange[ALOADM] = oprange[r];
  409. repop[ALOADM] = 1;
  410. oprange[ASTOREM] = oprange[r];
  411. repop[ASTOREM] = 1;
  412. oprange[AMOVF] = oprange[r];
  413. repop[AMOVF] = 1;
  414. oprange[AMOVLD] = oprange[r];
  415. repop[AMOVLD] = 1;
  416. oprange[AMOVLF] = oprange[r];
  417. repop[AMOVLF] = 1;
  418. oprange[AMOVFD] = oprange[r];
  419. repop[AMOVFD] = 1;
  420. oprange[AMOVDF] = oprange[r];
  421. repop[AMOVDF] = 1;
  422. oprange[AMOVFL] = oprange[r];
  423. repop[AMOVFL] = 1;
  424. oprange[AMOVDL] = oprange[r];
  425. repop[AMOVDL] = 1;
  426. break;
  427. case AADDL:
  428. buildrep(2, r);
  429. oprange[ASUBL] = oprange[r];
  430. repop[ASUBL] = 2;
  431. oprange[AMULL] = oprange[r];
  432. repop[AMULL] = 2;
  433. oprange[AMULUL] = oprange[r];
  434. repop[AMULUL] = 2;
  435. oprange[ASUBL] = oprange[r];
  436. repop[ASUBL] = 2;
  437. oprange[AANDL] = oprange[r];
  438. repop[AANDL] = 2;
  439. oprange[AORL] = oprange[r];
  440. repop[AORL] = 2;
  441. oprange[AXORL] = oprange[r];
  442. repop[AXORL] = 2;
  443. oprange[AISUBL] = oprange[r];
  444. repop[AISUBL] = 2;
  445. oprange[ANANDL] = oprange[r];
  446. repop[ANANDL] = 2;
  447. oprange[ANORL] = oprange[r];
  448. repop[ANORL] = 2;
  449. oprange[AXNORL] = oprange[r];
  450. repop[AXNORL] = 2;
  451. oprange[ASRAL] = oprange[r];
  452. repop[ASRAL] = 2;
  453. oprange[ASRLL] = oprange[r];
  454. repop[ASRLL] = 2;
  455. oprange[ASLLL] = oprange[r];
  456. repop[ASLLL] = 2;
  457. oprange[ACPNEQL] = oprange[r];
  458. repop[ACPNEQL] = 2;
  459. oprange[ACPLTUL] = oprange[r];
  460. repop[ACPLTUL] = 2;
  461. oprange[ACPLTL] = oprange[r];
  462. repop[ACPLTL] = 2;
  463. oprange[ACPLEUL] = oprange[r];
  464. repop[ACPLEUL] = 2;
  465. oprange[ACPLEL] = oprange[r];
  466. repop[ACPLEL] = 2;
  467. oprange[ACPGTUL] = oprange[r];
  468. repop[ACPGTUL] = 2;
  469. oprange[ACPGTL] = oprange[r];
  470. repop[ACPGTL] = 2;
  471. oprange[ACPGEUL] = oprange[r];
  472. repop[ACPGEUL] = 2;
  473. oprange[ACPGEL] = oprange[r];
  474. repop[ACPGEL] = 2;
  475. oprange[ACPEQL] = oprange[r];
  476. repop[ACPEQL] = 2;
  477. oprange[AMSTEPL] = oprange[r];
  478. repop[AMSTEPL] = 2;
  479. oprange[AMSTEPUL] = oprange[r];
  480. repop[AMSTEPUL] = 2;
  481. oprange[AMSTEPLL] = oprange[r];
  482. repop[AMSTEPLL] = 2;
  483. oprange[AMULL] = oprange[r];
  484. repop[AMULL] = 2;
  485. oprange[AMULUL] = oprange[r];
  486. repop[AMULUL] = 2;
  487. oprange[AMULML] = oprange[r];
  488. repop[AMULML] = 2;
  489. oprange[AMULMUL] = oprange[r];
  490. repop[AMULMUL] = 2;
  491. oprange[ADSTEPL] = oprange[r];
  492. repop[ADSTEPL] = 2;
  493. oprange[ADSTEP0L] = oprange[r];
  494. repop[ADSTEP0L] = 2;
  495. oprange[ADSTEPLL] = oprange[r];
  496. repop[ADSTEPLL] = 2;
  497. oprange[ADSTEPRL] = oprange[r];
  498. repop[ADSTEPRL] = 2;
  499. break;
  500. case AJMPF:
  501. buildrep(3, r);
  502. oprange[AJMPT] = oprange[r];
  503. repop[AJMPT] = 3;
  504. break;
  505. case AINV:
  506. buildrep(4, r);
  507. oprange[AIRETINV] = oprange[r];
  508. repop[AIRETINV] = 4;
  509. break;
  510. case AIRET:
  511. buildrep(5, r);
  512. oprange[AHALT] = oprange[r];
  513. repop[AHALT] = 5;
  514. break;
  515. case ALOADM:
  516. buildrep(6, r);
  517. oprange[ALOADSET] = oprange[r];
  518. repop[ALOADSET] = 6;
  519. break;
  520. case AADDD:
  521. buildrep(7, r);
  522. oprange[ASUBD] = oprange[r];
  523. repop[ASUBD] = 7;
  524. oprange[AMULD] = oprange[r];
  525. repop[AMULD] = 7;
  526. oprange[ADIVD] = oprange[r];
  527. repop[ADIVD] = 7;
  528. oprange[AADDF] = oprange[r];
  529. repop[AADDF] = 7;
  530. oprange[ASUBF] = oprange[r];
  531. repop[ASUBF] = 7;
  532. oprange[AMULF] = oprange[r];
  533. repop[AMULF] = 7;
  534. oprange[ADIVF] = oprange[r];
  535. repop[ADIVF] = 7;
  536. oprange[AGTD] = oprange[r];
  537. repop[AGTD] = 7;
  538. oprange[AGED] = oprange[r];
  539. repop[AGED] = 7;
  540. oprange[AEQD] = oprange[r];
  541. repop[AEQD] = 7;
  542. oprange[AGTF] = oprange[r];
  543. repop[AGTF] = 7;
  544. oprange[AGEF] = oprange[r];
  545. repop[AGEF] = 7;
  546. oprange[AEQF] = oprange[r];
  547. repop[AEQF] = 7;
  548. break;
  549. case ASTOREM:
  550. case AJMP:
  551. case AWORD:
  552. case ACALL:
  553. case AJMPFDEC:
  554. case ATEXT:
  555. case ADELAY:
  556. case AEMULATE:
  557. case ASETIP:
  558. case AMTSR:
  559. case AMFSR:
  560. case AMOVD:
  561. break;
  562. }
  563. }
  564. }
  565. void
  566. buildrep(int x, int as)
  567. {
  568. Opcross *p;
  569. Optab *e, *s, *o;
  570. int a1, a2, a3, n;
  571. if(C_NONE != 0 || C_REG != 1 || C_GOK >= 32 || x >= nelem(opcross)) {
  572. diag("assumptions fail in buildrep");
  573. errorexit();
  574. }
  575. repop[as] = x;
  576. p = (opcross + x);
  577. s = oprange[as].start;
  578. e = oprange[as].stop;
  579. for(o=e-1; o>=s; o--) {
  580. n = o-optab;
  581. for(a2=0; a2<2; a2++) {
  582. if(a2) {
  583. if(o->a2 == C_NONE)
  584. continue;
  585. } else
  586. if(o->a2 != C_NONE)
  587. continue;
  588. for(a1=0; a1<32; a1++) {
  589. if(!xcmp[a1][o->a1])
  590. continue;
  591. for(a3=0; a3<32; a3++)
  592. if(xcmp[a3][o->a3])
  593. (*p)[a1][a2][a3] = n+1;
  594. }
  595. }
  596. }
  597. oprange[as].start = 0;
  598. }