span.c 10 KB

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