span.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  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. if(instoffset == 0)
  167. return C_ZCON;
  168. if(instoffset >= -0x1000 && instoffset <= 0xfff)
  169. return C_SCON;
  170. if((instoffset & 0x3ff) == 0)
  171. return C_UCON;
  172. return C_LCON;
  173. case D_AUTO:
  174. instoffset = autosize + a->offset;
  175. if(instoffset >= -BIG && instoffset < BIG)
  176. return C_SACON;
  177. return C_LACON;
  178. case D_PARAM:
  179. instoffset = autosize + a->offset + 4L;
  180. if(instoffset >= -BIG && instoffset < BIG)
  181. return C_SACON;
  182. return C_LACON;
  183. }
  184. return C_GOK;
  185. case D_BRANCH:
  186. return C_SBRA;
  187. }
  188. return C_GOK;
  189. }
  190. Optab*
  191. oplook(Prog *p)
  192. {
  193. int a1, a2, a3, r;
  194. char *c1, *c3;
  195. Optab *o, *e;
  196. a1 = p->optab;
  197. if(a1)
  198. return optab+(a1-1);
  199. a1 = p->from.class;
  200. if(a1 == 0) {
  201. a1 = aclass(&p->from) + 1;
  202. p->from.class = a1;
  203. }
  204. a1--;
  205. a3 = p->to.class;
  206. if(a3 == 0) {
  207. a3 = aclass(&p->to) + 1;
  208. p->to.class = a3;
  209. }
  210. a3--;
  211. a2 = C_NONE;
  212. if(p->reg != NREG)
  213. a2 = C_REG;
  214. r = p->as;
  215. o = oprange[r].start;
  216. if(o == 0)
  217. o = oprange[r].stop; /* just generate an error */
  218. e = oprange[r].stop;
  219. c1 = xcmp[a1];
  220. c3 = xcmp[a3];
  221. for(; o<e; o++)
  222. if(o->a2 == a2)
  223. if(c1[o->a1])
  224. if(c3[o->a3]) {
  225. p->optab = (o-optab)+1;
  226. return o;
  227. }
  228. diag("illegal combination %A %d %d %d",
  229. p->as, a1, a2, a3);
  230. if(1||!debug['a'])
  231. prasm(p);
  232. if(o == 0)
  233. errorexit();
  234. return o;
  235. }
  236. int
  237. cmp(int a, int b)
  238. {
  239. if(a == b)
  240. return 1;
  241. switch(a) {
  242. case C_LCON:
  243. if(b == C_ZCON || b == C_SCON || b == C_UCON)
  244. return 1;
  245. break;
  246. case C_UCON:
  247. if(b == C_ZCON)
  248. return 1;
  249. break;
  250. case C_SCON:
  251. if(b == C_ZCON)
  252. return 1;
  253. break;
  254. case C_LACON:
  255. if(b == C_SACON)
  256. return 1;
  257. break;
  258. case C_LBRA:
  259. if(b == C_SBRA)
  260. return 1;
  261. break;
  262. case C_ELEXT:
  263. if(b == C_ESEXT)
  264. return 1;
  265. break;
  266. case C_LEXT:
  267. if(b == C_SEXT ||
  268. b == C_ESEXT || b == C_OSEXT ||
  269. b == C_ELEXT || b == C_OLEXT)
  270. return 1;
  271. break;
  272. case C_SEXT:
  273. if(b == C_ESEXT || b == C_OSEXT)
  274. return 1;
  275. break;
  276. case C_ELAUTO:
  277. if(b == C_ESAUTO)
  278. return 1;
  279. break;
  280. case C_LAUTO:
  281. if(b == C_SAUTO ||
  282. b == C_ESAUTO || b == C_OSAUTO ||
  283. b == C_ELAUTO || b == C_OLAUTO)
  284. return 1;
  285. break;
  286. case C_SAUTO:
  287. if(b == C_ESAUTO || b == C_OSAUTO)
  288. return 1;
  289. break;
  290. case C_REG:
  291. if(b == C_ZCON)
  292. return 1;
  293. break;
  294. case C_LOREG:
  295. if(b == C_ZOREG || b == C_SOREG)
  296. return 1;
  297. break;
  298. case C_SOREG:
  299. if(b == C_ZOREG)
  300. return 1;
  301. break;
  302. case C_ANY:
  303. return 1;
  304. }
  305. return 0;
  306. }
  307. int
  308. ocmp(const void *a1, const void *a2)
  309. {
  310. Optab *p1, *p2;
  311. int n;
  312. p1 = (Optab*)a1;
  313. p2 = (Optab*)a2;
  314. n = p1->as - p2->as;
  315. if(n)
  316. return n;
  317. n = p1->a1 - p2->a1;
  318. if(n)
  319. return n;
  320. n = p1->a2 - p2->a2;
  321. if(n)
  322. return n;
  323. n = p1->a3 - p2->a3;
  324. if(n)
  325. return n;
  326. return 0;
  327. }
  328. void
  329. buildop(void)
  330. {
  331. int i, n, r;
  332. for(i=0; i<C_NCLASS; i++)
  333. for(n=0; n<C_NCLASS; n++)
  334. xcmp[i][n] = cmp(n, i);
  335. for(n=0; optab[n].as != AXXX; n++)
  336. ;
  337. qsort(optab, n, sizeof(optab[0]), ocmp);
  338. for(i=0; i<n; i++) {
  339. r = optab[i].as;
  340. oprange[r].start = optab+i;
  341. while(optab[i].as == r)
  342. i++;
  343. oprange[r].stop = optab+i;
  344. i--;
  345. switch(r)
  346. {
  347. default:
  348. diag("unknown op in build: %A", r);
  349. errorexit();
  350. case AADD:
  351. oprange[AADDX] = oprange[r];
  352. oprange[ASUB] = oprange[r];
  353. oprange[ASUBX] = oprange[r];
  354. oprange[AMUL] = oprange[r];
  355. oprange[AXOR] = oprange[r];
  356. oprange[AXNOR] = oprange[r];
  357. oprange[AAND] = oprange[r];
  358. oprange[AANDN] = oprange[r];
  359. oprange[AOR] = oprange[r];
  360. oprange[AORN] = oprange[r];
  361. oprange[ASLL] = oprange[r];
  362. oprange[ASRL] = oprange[r];
  363. oprange[ASRA] = oprange[r];
  364. oprange[AADDCC] = oprange[r];
  365. oprange[AADDXCC] = oprange[r];
  366. oprange[ATADDCC] = oprange[r];
  367. oprange[ATADDCCTV] = oprange[r];
  368. oprange[ASUBCC] = oprange[r];
  369. oprange[ASUBXCC] = oprange[r];
  370. oprange[ATSUBCC] = oprange[r];
  371. oprange[ATSUBCCTV] = oprange[r];
  372. oprange[AXORCC] = oprange[r];
  373. oprange[AXNORCC] = oprange[r];
  374. oprange[AANDCC] = oprange[r];
  375. oprange[AANDNCC] = oprange[r];
  376. oprange[AORCC] = oprange[r];
  377. oprange[AORNCC] = oprange[r];
  378. oprange[AMULSCC] = oprange[r];
  379. oprange[ASAVE] = oprange[r];
  380. oprange[ARESTORE] = oprange[r];
  381. break;
  382. case AMOVB:
  383. oprange[AMOVH] = oprange[r];
  384. oprange[AMOVHU] = oprange[r];
  385. oprange[AMOVBU] = oprange[r];
  386. oprange[ASWAP] = oprange[r];
  387. oprange[ATAS] = oprange[r];
  388. break;
  389. case ABA:
  390. oprange[ABN] = oprange[r];
  391. oprange[AFBA] = oprange[r];
  392. oprange[AFBN] = oprange[r];
  393. break;
  394. case ABE:
  395. oprange[ABCC] = oprange[r];
  396. oprange[ABCS] = oprange[r];
  397. oprange[ABGE] = oprange[r];
  398. oprange[ABGU] = oprange[r];
  399. oprange[ABG] = oprange[r];
  400. oprange[ABLEU] = oprange[r];
  401. oprange[ABLE] = oprange[r];
  402. oprange[ABL] = oprange[r];
  403. oprange[ABNEG] = oprange[r];
  404. oprange[ABNE] = oprange[r];
  405. oprange[ABPOS] = oprange[r];
  406. oprange[ABVC] = oprange[r];
  407. oprange[ABVS] = oprange[r];
  408. oprange[AFBE] = oprange[r];
  409. oprange[AFBG] = oprange[r];
  410. oprange[AFBGE] = oprange[r];
  411. oprange[AFBL] = oprange[r];
  412. oprange[AFBLE] = oprange[r];
  413. oprange[AFBLG] = oprange[r];
  414. oprange[AFBNE] = oprange[r];
  415. oprange[AFBO] = oprange[r];
  416. oprange[AFBU] = oprange[r];
  417. oprange[AFBUE] = oprange[r];
  418. oprange[AFBUG] = oprange[r];
  419. oprange[AFBUGE] = oprange[r];
  420. oprange[AFBUL] = oprange[r];
  421. oprange[AFBULE] = oprange[r];
  422. break;
  423. case ATA:
  424. oprange[ATCC] = oprange[r];
  425. oprange[ATCS] = oprange[r];
  426. oprange[ATE] = oprange[r];
  427. oprange[ATGE] = oprange[r];
  428. oprange[ATGU] = oprange[r];
  429. oprange[ATG] = oprange[r];
  430. oprange[ATLEU] = oprange[r];
  431. oprange[ATLE] = oprange[r];
  432. oprange[ATL] = oprange[r];
  433. oprange[ATNEG] = oprange[r];
  434. oprange[ATNE] = oprange[r];
  435. oprange[ATN] = oprange[r];
  436. oprange[ATPOS] = oprange[r];
  437. oprange[ATVC] = oprange[r];
  438. oprange[ATVS] = oprange[r];
  439. break;
  440. case AFADDD:
  441. oprange[AFADDF] = oprange[r];
  442. oprange[AFADDX] = oprange[r];
  443. oprange[AFDIVD] = oprange[r];
  444. oprange[AFDIVF] = oprange[r];
  445. oprange[AFDIVX] = oprange[r];
  446. oprange[AFMULD] = oprange[r];
  447. oprange[AFMULF] = oprange[r];
  448. oprange[AFMULX] = oprange[r];
  449. oprange[AFSUBD] = oprange[r];
  450. oprange[AFSUBF] = oprange[r];
  451. oprange[AFSUBX] = oprange[r];
  452. break;
  453. case AFCMPD:
  454. oprange[AFCMPF] = oprange[r];
  455. oprange[AFCMPX] = oprange[r];
  456. oprange[AFCMPED] = oprange[r];
  457. oprange[AFCMPEF] = oprange[r];
  458. oprange[AFCMPEX] = oprange[r];
  459. break;
  460. case AFABSF:
  461. oprange[AFMOVDF] = oprange[r];
  462. oprange[AFMOVDW] = oprange[r];
  463. oprange[AFMOVFD] = oprange[r];
  464. oprange[AFMOVFW] = oprange[r];
  465. oprange[AFMOVWD] = oprange[r];
  466. oprange[AFMOVWF] = oprange[r];
  467. oprange[AFNEGF] = oprange[r];
  468. oprange[AFSQRTD] = oprange[r];
  469. oprange[AFSQRTF] = oprange[r];
  470. break;
  471. case AFMOVF:
  472. case AFMOVD:
  473. case AMOVW:
  474. case AMOVD:
  475. case AWORD:
  476. case ARETT:
  477. case AJMPL:
  478. case AJMP:
  479. case ACMP:
  480. case ANOP:
  481. case ATEXT:
  482. case ADIV:
  483. case ADIVL:
  484. case AMOD:
  485. case AMODL:
  486. break;
  487. }
  488. }
  489. }