span.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. #include "l.h"
  2. void
  3. span(void)
  4. {
  5. Prog *p;
  6. Sym *setext;
  7. Optab *o;
  8. int m;
  9. long c;
  10. if(debug['v'])
  11. Bprint(&bso, "%5.2f span\n", cputime());
  12. Bflush(&bso);
  13. c = INITTEXT;
  14. for(p = firstp; p != P; p = p->link) {
  15. p->pc = c;
  16. o = oplook(p);
  17. m = o->size;
  18. if(m == 0) {
  19. if(p->as == ATEXT) {
  20. curtext = p;
  21. autosize = p->to.offset + 4;
  22. if(p->from.sym != S)
  23. p->from.sym->value = c;
  24. continue;
  25. }
  26. if(p->as != ANOP)
  27. diag("zero-width instruction\n%P", p);
  28. continue;
  29. }
  30. c += m;
  31. }
  32. c = rnd(c, 8);
  33. setext = lookup("etext", 0);
  34. if(setext != S) {
  35. setext->value = c;
  36. textsize = c - INITTEXT;
  37. }
  38. if(INITRND)
  39. INITDAT = rnd(c, INITRND);
  40. if(debug['v'])
  41. Bprint(&bso, "tsize = %lux\n", textsize);
  42. Bflush(&bso);
  43. }
  44. void
  45. xdefine(char *p, int t, long v)
  46. {
  47. Sym *s;
  48. s = lookup(p, 0);
  49. if(s->type == 0 || s->type == SXREF) {
  50. s->type = t;
  51. s->value = v;
  52. }
  53. }
  54. long
  55. regoff(Adr *a)
  56. {
  57. instoffset = 0;
  58. aclass(a);
  59. return instoffset;
  60. }
  61. int
  62. aclass(Adr *a)
  63. {
  64. Sym *s;
  65. int t;
  66. switch(a->type) {
  67. case D_NONE:
  68. return C_NONE;
  69. case D_REG:
  70. return C_REG;
  71. case D_FREG:
  72. return C_FREG;
  73. case D_CREG:
  74. return C_CREG;
  75. case D_PREG:
  76. if(a->reg == D_FSR)
  77. return C_FSR;
  78. if(a->reg == D_FPQ)
  79. return C_FQ;
  80. return C_PREG;
  81. case D_OREG:
  82. switch(a->name) {
  83. case D_EXTERN:
  84. case D_STATIC:
  85. if(a->sym == S)
  86. break;
  87. t = a->sym->type;
  88. if(t == 0 || t == SXREF) {
  89. diag("undefined external: %s in %s",
  90. a->sym->name, TNAME);
  91. a->sym->type = SDATA;
  92. }
  93. instoffset = a->sym->value + a->offset - BIG;
  94. if(instoffset >= -BIG && instoffset < BIG) {
  95. if(instoffset & 7)
  96. return C_OSEXT;
  97. return C_ESEXT;
  98. }
  99. if(instoffset & 7)
  100. return C_OLEXT;
  101. return C_ELEXT;
  102. case D_AUTO:
  103. instoffset = autosize + a->offset;
  104. goto dauto;
  105. case D_PARAM:
  106. instoffset = autosize + a->offset + 4L;
  107. dauto:
  108. if(instoffset >= -BIG && instoffset < BIG) {
  109. if(instoffset & 7)
  110. return C_OSAUTO;
  111. return C_ESAUTO;
  112. }
  113. if(instoffset & 7)
  114. return C_OLAUTO;
  115. return C_ELAUTO;
  116. case D_NONE:
  117. instoffset = a->offset;
  118. if(instoffset == 0)
  119. return C_ZOREG;
  120. if(instoffset >= -BIG && instoffset < BIG)
  121. return C_SOREG;
  122. return C_LOREG;
  123. }
  124. return C_GOK;
  125. case D_ASI:
  126. if(a->name == D_NONE)
  127. return C_ASI;
  128. return C_GOK;
  129. case D_CONST:
  130. switch(a->name) {
  131. case D_NONE:
  132. instoffset = a->offset;
  133. consize:
  134. if(instoffset == 0)
  135. return C_ZCON;
  136. if(instoffset >= -0x1000 && instoffset <= 0xfff)
  137. return C_SCON;
  138. if((instoffset & 0x3ff) == 0)
  139. return C_UCON;
  140. return C_LCON;
  141. case D_EXTERN:
  142. case D_STATIC:
  143. s = a->sym;
  144. if(s == S)
  145. break;
  146. t = s->type;
  147. if(t == 0 || t == SXREF) {
  148. diag("undefined external: %s in %s",
  149. s->name, TNAME);
  150. s->type = SDATA;
  151. }
  152. if(s->type == STEXT || s->type == SLEAF) {
  153. instoffset = s->value + a->offset;
  154. return C_LCON;
  155. }
  156. if(s->type == SCONST) {
  157. instoffset = s->value + a->offset;
  158. goto consize;
  159. }
  160. instoffset = s->value + a->offset - BIG;
  161. if(instoffset >= -BIG && instoffset < BIG && instoffset != 0)
  162. return C_SECON;
  163. instoffset = s->value + a->offset + INITDAT;
  164. /* not sure why this barfs */
  165. return C_LCON;
  166. /*
  167. if(instoffset == 0)
  168. return C_ZCON;
  169. if(instoffset >= -0x1000 && instoffset <= 0xfff)
  170. return C_SCON;
  171. if((instoffset & 0x3ff) == 0)
  172. return C_UCON;
  173. return C_LCON;
  174. */
  175. case D_AUTO:
  176. instoffset = autosize + a->offset;
  177. if(instoffset >= -BIG && instoffset < BIG)
  178. return C_SACON;
  179. return C_LACON;
  180. case D_PARAM:
  181. instoffset = autosize + a->offset + 4L;
  182. if(instoffset >= -BIG && instoffset < BIG)
  183. return C_SACON;
  184. return C_LACON;
  185. }
  186. return C_GOK;
  187. case D_BRANCH:
  188. return C_SBRA;
  189. }
  190. return C_GOK;
  191. }
  192. Optab*
  193. oplook(Prog *p)
  194. {
  195. int a1, a2, a3, r;
  196. char *c1, *c3;
  197. Optab *o, *e;
  198. a1 = p->optab;
  199. if(a1)
  200. return optab+(a1-1);
  201. a1 = p->from.class;
  202. if(a1 == 0) {
  203. a1 = aclass(&p->from) + 1;
  204. p->from.class = a1;
  205. }
  206. a1--;
  207. a3 = p->to.class;
  208. if(a3 == 0) {
  209. a3 = aclass(&p->to) + 1;
  210. p->to.class = a3;
  211. }
  212. a3--;
  213. a2 = C_NONE;
  214. if(p->reg != NREG)
  215. a2 = C_REG;
  216. r = p->as;
  217. o = oprange[r].start;
  218. if(o == 0)
  219. o = oprange[r].stop; /* just generate an error */
  220. e = oprange[r].stop;
  221. c1 = xcmp[a1];
  222. c3 = xcmp[a3];
  223. for(; o<e; o++)
  224. if(o->a2 == a2)
  225. if(c1[o->a1])
  226. if(c3[o->a3]) {
  227. p->optab = (o-optab)+1;
  228. return o;
  229. }
  230. diag("illegal combination %A %d %d %d",
  231. p->as, a1, a2, a3);
  232. if(1||!debug['a'])
  233. prasm(p);
  234. if(o == 0)
  235. errorexit();
  236. return o;
  237. }
  238. int
  239. cmp(int a, int b)
  240. {
  241. if(a == b)
  242. return 1;
  243. switch(a) {
  244. case C_LCON:
  245. if(b == C_ZCON || b == C_SCON || b == C_UCON)
  246. return 1;
  247. break;
  248. case C_UCON:
  249. if(b == C_ZCON)
  250. return 1;
  251. break;
  252. case C_SCON:
  253. if(b == C_ZCON)
  254. return 1;
  255. break;
  256. case C_LACON:
  257. if(b == C_SACON)
  258. return 1;
  259. break;
  260. case C_LBRA:
  261. if(b == C_SBRA)
  262. return 1;
  263. break;
  264. case C_ELEXT:
  265. if(b == C_ESEXT)
  266. return 1;
  267. break;
  268. case C_LEXT:
  269. if(b == C_SEXT ||
  270. b == C_ESEXT || b == C_OSEXT ||
  271. b == C_ELEXT || b == C_OLEXT)
  272. return 1;
  273. break;
  274. case C_SEXT:
  275. if(b == C_ESEXT || b == C_OSEXT)
  276. return 1;
  277. break;
  278. case C_ELAUTO:
  279. if(b == C_ESAUTO)
  280. return 1;
  281. break;
  282. case C_LAUTO:
  283. if(b == C_SAUTO ||
  284. b == C_ESAUTO || b == C_OSAUTO ||
  285. b == C_ELAUTO || b == C_OLAUTO)
  286. return 1;
  287. break;
  288. case C_SAUTO:
  289. if(b == C_ESAUTO || b == C_OSAUTO)
  290. return 1;
  291. break;
  292. case C_REG:
  293. if(b == C_ZCON)
  294. return 1;
  295. break;
  296. case C_LOREG:
  297. if(b == C_ZOREG || b == C_SOREG)
  298. return 1;
  299. break;
  300. case C_SOREG:
  301. if(b == C_ZOREG)
  302. return 1;
  303. break;
  304. case C_ANY:
  305. return 1;
  306. }
  307. return 0;
  308. }
  309. int
  310. ocmp(const void *a1, const void *a2)
  311. {
  312. Optab *p1, *p2;
  313. int n;
  314. p1 = (Optab*)a1;
  315. p2 = (Optab*)a2;
  316. n = p1->as - p2->as;
  317. if(n)
  318. return n;
  319. n = p1->a1 - p2->a1;
  320. if(n)
  321. return n;
  322. n = p1->a2 - p2->a2;
  323. if(n)
  324. return n;
  325. n = p1->a3 - p2->a3;
  326. if(n)
  327. return n;
  328. return 0;
  329. }
  330. void
  331. buildop(void)
  332. {
  333. int i, n, r;
  334. for(i=0; i<C_NCLASS; i++)
  335. for(n=0; n<C_NCLASS; n++)
  336. xcmp[i][n] = cmp(n, i);
  337. for(n=0; optab[n].as != AXXX; n++)
  338. ;
  339. qsort(optab, n, sizeof(optab[0]), ocmp);
  340. for(i=0; i<n; i++) {
  341. r = optab[i].as;
  342. oprange[r].start = optab+i;
  343. while(optab[i].as == r)
  344. i++;
  345. oprange[r].stop = optab+i;
  346. i--;
  347. switch(r)
  348. {
  349. default:
  350. diag("unknown op in build: %A", r);
  351. errorexit();
  352. case AADD:
  353. oprange[AADDX] = oprange[r];
  354. oprange[ASUB] = oprange[r];
  355. oprange[ASUBX] = oprange[r];
  356. oprange[AMUL] = oprange[r];
  357. oprange[AXOR] = oprange[r];
  358. oprange[AXNOR] = oprange[r];
  359. oprange[AAND] = oprange[r];
  360. oprange[AANDN] = oprange[r];
  361. oprange[AOR] = oprange[r];
  362. oprange[AORN] = oprange[r];
  363. oprange[ASLL] = oprange[r];
  364. oprange[ASRL] = oprange[r];
  365. oprange[ASRA] = oprange[r];
  366. oprange[AADDCC] = oprange[r];
  367. oprange[AADDXCC] = oprange[r];
  368. oprange[ATADDCC] = oprange[r];
  369. oprange[ATADDCCTV] = oprange[r];
  370. oprange[ASUBCC] = oprange[r];
  371. oprange[ASUBXCC] = oprange[r];
  372. oprange[ATSUBCC] = oprange[r];
  373. oprange[ATSUBCCTV] = oprange[r];
  374. oprange[AXORCC] = oprange[r];
  375. oprange[AXNORCC] = oprange[r];
  376. oprange[AANDCC] = oprange[r];
  377. oprange[AANDNCC] = oprange[r];
  378. oprange[AORCC] = oprange[r];
  379. oprange[AORNCC] = oprange[r];
  380. oprange[AMULSCC] = oprange[r];
  381. oprange[ASAVE] = oprange[r];
  382. oprange[ARESTORE] = oprange[r];
  383. break;
  384. case AMOVB:
  385. oprange[AMOVH] = oprange[r];
  386. oprange[AMOVHU] = oprange[r];
  387. oprange[AMOVBU] = oprange[r];
  388. oprange[ASWAP] = oprange[r];
  389. oprange[ATAS] = oprange[r];
  390. break;
  391. case ABA:
  392. oprange[ABN] = oprange[r];
  393. oprange[AFBA] = oprange[r];
  394. oprange[AFBN] = oprange[r];
  395. break;
  396. case ABE:
  397. oprange[ABCC] = oprange[r];
  398. oprange[ABCS] = oprange[r];
  399. oprange[ABGE] = oprange[r];
  400. oprange[ABGU] = oprange[r];
  401. oprange[ABG] = oprange[r];
  402. oprange[ABLEU] = oprange[r];
  403. oprange[ABLE] = oprange[r];
  404. oprange[ABL] = oprange[r];
  405. oprange[ABNEG] = oprange[r];
  406. oprange[ABNE] = oprange[r];
  407. oprange[ABPOS] = oprange[r];
  408. oprange[ABVC] = oprange[r];
  409. oprange[ABVS] = oprange[r];
  410. oprange[AFBE] = oprange[r];
  411. oprange[AFBG] = oprange[r];
  412. oprange[AFBGE] = oprange[r];
  413. oprange[AFBL] = oprange[r];
  414. oprange[AFBLE] = oprange[r];
  415. oprange[AFBLG] = oprange[r];
  416. oprange[AFBNE] = oprange[r];
  417. oprange[AFBO] = oprange[r];
  418. oprange[AFBU] = oprange[r];
  419. oprange[AFBUE] = oprange[r];
  420. oprange[AFBUG] = oprange[r];
  421. oprange[AFBUGE] = oprange[r];
  422. oprange[AFBUL] = oprange[r];
  423. oprange[AFBULE] = oprange[r];
  424. break;
  425. case ATA:
  426. oprange[ATCC] = oprange[r];
  427. oprange[ATCS] = oprange[r];
  428. oprange[ATE] = oprange[r];
  429. oprange[ATGE] = oprange[r];
  430. oprange[ATGU] = oprange[r];
  431. oprange[ATG] = oprange[r];
  432. oprange[ATLEU] = oprange[r];
  433. oprange[ATLE] = oprange[r];
  434. oprange[ATL] = oprange[r];
  435. oprange[ATNEG] = oprange[r];
  436. oprange[ATNE] = oprange[r];
  437. oprange[ATN] = oprange[r];
  438. oprange[ATPOS] = oprange[r];
  439. oprange[ATVC] = oprange[r];
  440. oprange[ATVS] = oprange[r];
  441. break;
  442. case AFADDD:
  443. oprange[AFADDF] = oprange[r];
  444. oprange[AFADDX] = oprange[r];
  445. oprange[AFDIVD] = oprange[r];
  446. oprange[AFDIVF] = oprange[r];
  447. oprange[AFDIVX] = oprange[r];
  448. oprange[AFMULD] = oprange[r];
  449. oprange[AFMULF] = oprange[r];
  450. oprange[AFMULX] = oprange[r];
  451. oprange[AFSUBD] = oprange[r];
  452. oprange[AFSUBF] = oprange[r];
  453. oprange[AFSUBX] = oprange[r];
  454. break;
  455. case AFCMPD:
  456. oprange[AFCMPF] = oprange[r];
  457. oprange[AFCMPX] = oprange[r];
  458. oprange[AFCMPED] = oprange[r];
  459. oprange[AFCMPEF] = oprange[r];
  460. oprange[AFCMPEX] = oprange[r];
  461. break;
  462. case AFABSF:
  463. oprange[AFMOVDF] = oprange[r];
  464. oprange[AFMOVDW] = oprange[r];
  465. oprange[AFMOVFD] = oprange[r];
  466. oprange[AFMOVFW] = oprange[r];
  467. oprange[AFMOVWD] = oprange[r];
  468. oprange[AFMOVWF] = oprange[r];
  469. oprange[AFNEGF] = oprange[r];
  470. oprange[AFSQRTD] = oprange[r];
  471. oprange[AFSQRTF] = oprange[r];
  472. break;
  473. case AFMOVF:
  474. case AFMOVD:
  475. case AMOVW:
  476. case AMOVD:
  477. case AWORD:
  478. case ARETT:
  479. case AJMPL:
  480. case AJMP:
  481. case ACMP:
  482. case ANOP:
  483. case ATEXT:
  484. case ADIV:
  485. case ADIVL:
  486. case AMOD:
  487. case AMODL:
  488. break;
  489. }
  490. }
  491. }