span.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978
  1. #include "l.h"
  2. static struct {
  3. ulong start;
  4. ulong size;
  5. } pool;
  6. void checkpool(Prog*);
  7. void flushpool(Prog*, int);
  8. void
  9. span(void)
  10. {
  11. Prog *p;
  12. Sym *setext, *s;
  13. Optab *o;
  14. int m, bflag, i;
  15. long c, otxt, v;
  16. if(debug['v'])
  17. Bprint(&bso, "%5.2f span\n", cputime());
  18. Bflush(&bso);
  19. bflag = 0;
  20. c = INITTEXT;
  21. otxt = c;
  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. /* need passes to resolve branches */
  33. if(c-otxt >= 1L<<17)
  34. bflag = 1;
  35. otxt = c;
  36. continue;
  37. }
  38. diag("zero-width instruction\n%P", p);
  39. continue;
  40. }
  41. switch(o->flag & (LFROM|LTO|LPOOL)) {
  42. case LFROM:
  43. addpool(p, &p->from);
  44. break;
  45. case LTO:
  46. addpool(p, &p->to);
  47. break;
  48. case LPOOL:
  49. if ((p->scond&C_SCOND) == 14)
  50. flushpool(p, 0);
  51. break;
  52. }
  53. if(p->as==AMOVW && p->to.type==D_REG && p->to.reg==REGPC && (p->scond&C_SCOND) == 14)
  54. flushpool(p, 0);
  55. c += m;
  56. if(blitrl)
  57. checkpool(p);
  58. }
  59. /*
  60. * if any procedure is large enough to
  61. * generate a large SBRA branch, then
  62. * generate extra passes putting branches
  63. * around jmps to fix. this is rare.
  64. */
  65. while(bflag) {
  66. if(debug['v'])
  67. Bprint(&bso, "%5.2f span1\n", cputime());
  68. bflag = 0;
  69. c = INITTEXT;
  70. for(p = firstp; p != P; p = p->link) {
  71. p->pc = c;
  72. o = oplook(p);
  73. /* very larg branches
  74. if(o->type == 6 && p->cond) {
  75. otxt = p->cond->pc - c;
  76. if(otxt < 0)
  77. otxt = -otxt;
  78. if(otxt >= (1L<<17) - 10) {
  79. q = prg();
  80. q->link = p->link;
  81. p->link = q;
  82. q->as = AB;
  83. q->to.type = D_BRANCH;
  84. q->cond = p->cond;
  85. p->cond = q;
  86. q = prg();
  87. q->link = p->link;
  88. p->link = q;
  89. q->as = AB;
  90. q->to.type = D_BRANCH;
  91. q->cond = q->link->link;
  92. bflag = 1;
  93. }
  94. }
  95. */
  96. m = o->size;
  97. if(m == 0) {
  98. if(p->as == ATEXT) {
  99. curtext = p;
  100. autosize = p->to.offset + 4;
  101. if(p->from.sym != S)
  102. p->from.sym->value = c;
  103. continue;
  104. }
  105. diag("zero-width instruction\n%P", p);
  106. continue;
  107. }
  108. c += m;
  109. }
  110. }
  111. if(debug['t']) {
  112. /*
  113. * add strings to text segment
  114. */
  115. c = rnd(c, 8);
  116. for(i=0; i<NHASH; i++)
  117. for(s = hash[i]; s != S; s = s->link) {
  118. if(s->type != SSTRING)
  119. continue;
  120. v = s->value;
  121. while(v & 3)
  122. v++;
  123. s->value = c;
  124. c += v;
  125. }
  126. }
  127. c = rnd(c, 8);
  128. setext = lookup("etext", 0);
  129. if(setext != S) {
  130. setext->value = c;
  131. textsize = c - INITTEXT;
  132. }
  133. if(INITRND)
  134. INITDAT = rnd(c, INITRND);
  135. if(debug['v'])
  136. Bprint(&bso, "tsize = %lux\n", textsize);
  137. Bflush(&bso);
  138. }
  139. /*
  140. * when the first reference to the literal pool threatens
  141. * to go out of range of a 12-bit PC-relative offset,
  142. * drop the pool now, and branch round it.
  143. * this happens only in extended basic blocks that exceed 4k.
  144. */
  145. void
  146. checkpool(Prog *p)
  147. {
  148. if(pool.size >= 0xffc || immaddr((p->pc+4)+4+pool.size - pool.start+8) == 0)
  149. flushpool(p, 1);
  150. else if(p->link == P)
  151. flushpool(p, 2);
  152. }
  153. void
  154. flushpool(Prog *p, int skip)
  155. {
  156. Prog *q;
  157. if(blitrl) {
  158. if(skip){
  159. if(debug['v'] && skip == 1)
  160. print("note: flush literal pool at %lux: len=%lud ref=%lux\n", p->pc+4, pool.size, pool.start);
  161. q = prg();
  162. q->as = AB;
  163. q->to.type = D_BRANCH;
  164. q->cond = p->link;
  165. q->link = blitrl;
  166. blitrl = q;
  167. }
  168. else if(p->pc+pool.size-pool.start < 2048)
  169. return;
  170. elitrl->link = p->link;
  171. p->link = blitrl;
  172. blitrl = 0; /* BUG: should refer back to values until out-of-range */
  173. elitrl = 0;
  174. pool.size = 0;
  175. pool.start = 0;
  176. }
  177. }
  178. void
  179. addpool(Prog *p, Adr *a)
  180. {
  181. Prog *q, t;
  182. int c;
  183. c = aclass(a);
  184. t = zprg;
  185. t.as = AWORD;
  186. switch(c) {
  187. default:
  188. t.to = *a;
  189. break;
  190. case C_SROREG:
  191. case C_LOREG:
  192. case C_ROREG:
  193. case C_FOREG:
  194. case C_SOREG:
  195. case C_FAUTO:
  196. case C_SAUTO:
  197. case C_LAUTO:
  198. case C_LACON:
  199. t.to.type = D_CONST;
  200. t.to.offset = instoffset;
  201. break;
  202. }
  203. for(q = blitrl; q != P; q = q->link) /* could hash on t.t0.offset */
  204. if(memcmp(&q->to, &t.to, sizeof(t.to)) == 0) {
  205. p->cond = q;
  206. return;
  207. }
  208. q = prg();
  209. *q = t;
  210. q->pc = pool.size;
  211. if(blitrl == P) {
  212. blitrl = q;
  213. pool.start = p->pc;
  214. } else
  215. elitrl->link = q;
  216. elitrl = q;
  217. pool.size += 4;
  218. p->cond = q;
  219. }
  220. void
  221. xdefine(char *p, int t, long v)
  222. {
  223. Sym *s;
  224. s = lookup(p, 0);
  225. if(s->type == 0 || s->type == SXREF) {
  226. s->type = t;
  227. s->value = v;
  228. }
  229. }
  230. long
  231. regoff(Adr *a)
  232. {
  233. instoffset = 0;
  234. aclass(a);
  235. return instoffset;
  236. }
  237. long
  238. immrot(ulong v)
  239. {
  240. int i;
  241. for(i=0; i<16; i++) {
  242. if((v & ~0xff) == 0)
  243. return (i<<8) | v | (1<<25);
  244. v = (v<<2) | (v>>30);
  245. }
  246. return 0;
  247. }
  248. long
  249. immaddr(long v)
  250. {
  251. if(v >= 0 && v <= 0xfff)
  252. return (v & 0xfff) |
  253. (1<<24) | /* pre indexing */
  254. (1<<23); /* pre indexing, up */
  255. if(v >= -0xfff && v < 0)
  256. return (-v & 0xfff) |
  257. (1<<24); /* pre indexing */
  258. return 0;
  259. }
  260. int
  261. immfloat(long v)
  262. {
  263. return (v & 0xC03) == 0; /* offset will fit in floating-point load/store */
  264. }
  265. int
  266. immhalf(long v)
  267. {
  268. if(v >= 0 && v <= 0xff)
  269. return v|
  270. (1<<24)| /* pre indexing */
  271. (1<<23); /* pre indexing, up */
  272. if(v >= -0xff && v < 0)
  273. return (-v & 0xff)|
  274. (1<<24); /* pre indexing */
  275. return 0;
  276. }
  277. int
  278. aclass(Adr *a)
  279. {
  280. Sym *s;
  281. int t;
  282. switch(a->type) {
  283. case D_NONE:
  284. return C_NONE;
  285. case D_REG:
  286. return C_REG;
  287. case D_REGREG:
  288. return C_REGREG;
  289. case D_SHIFT:
  290. return C_SHIFT;
  291. case D_FREG:
  292. return C_FREG;
  293. case D_FPCR:
  294. return C_FCR;
  295. case D_OREG:
  296. switch(a->name) {
  297. case D_EXTERN:
  298. case D_STATIC:
  299. if(a->sym == 0 || a->sym->name == 0) {
  300. print("null sym external\n");
  301. print("%D\n", a);
  302. return C_GOK;
  303. }
  304. s = a->sym;
  305. t = s->type;
  306. if(t == 0 || t == SXREF) {
  307. diag("undefined external: %s in %s",
  308. s->name, TNAME);
  309. s->type = SDATA;
  310. }
  311. if(dlm) {
  312. switch(t) {
  313. default:
  314. instoffset = s->value + a->offset + INITDAT;
  315. break;
  316. case SUNDEF:
  317. case STEXT:
  318. case SCONST:
  319. case SLEAF:
  320. case SSTRING:
  321. instoffset = s->value + a->offset;
  322. break;
  323. }
  324. return C_ADDR;
  325. }
  326. instoffset = s->value + a->offset - BIG;
  327. t = immaddr(instoffset);
  328. if(t) {
  329. if(immhalf(instoffset))
  330. return immfloat(t) ? C_HFEXT : C_HEXT;
  331. if(immfloat(t))
  332. return C_FEXT;
  333. return C_SEXT;
  334. }
  335. return C_LEXT;
  336. case D_AUTO:
  337. instoffset = autosize + a->offset;
  338. t = immaddr(instoffset);
  339. if(t){
  340. if(immhalf(instoffset))
  341. return immfloat(t) ? C_HFAUTO : C_HAUTO;
  342. if(immfloat(t))
  343. return C_FAUTO;
  344. return C_SAUTO;
  345. }
  346. return C_LAUTO;
  347. case D_PARAM:
  348. instoffset = autosize + a->offset + 4L;
  349. t = immaddr(instoffset);
  350. if(t){
  351. if(immhalf(instoffset))
  352. return immfloat(t) ? C_HFAUTO : C_HAUTO;
  353. if(immfloat(t))
  354. return C_FAUTO;
  355. return C_SAUTO;
  356. }
  357. return C_LAUTO;
  358. case D_NONE:
  359. instoffset = a->offset;
  360. t = immaddr(instoffset);
  361. if(t) {
  362. if(immhalf(instoffset)) /* n.b. that it will also satisfy immrot */
  363. return immfloat(t) ? C_HFOREG : C_HOREG;
  364. if(immfloat(t))
  365. return C_FOREG; /* n.b. that it will also satisfy immrot */
  366. t = immrot(instoffset);
  367. if(t)
  368. return C_SROREG;
  369. if(immhalf(instoffset))
  370. return C_HOREG;
  371. return C_SOREG;
  372. }
  373. t = immrot(instoffset);
  374. if(t)
  375. return C_ROREG;
  376. return C_LOREG;
  377. }
  378. return C_GOK;
  379. case D_PSR:
  380. return C_PSR;
  381. case D_OCONST:
  382. switch(a->name) {
  383. case D_EXTERN:
  384. case D_STATIC:
  385. s = a->sym;
  386. t = s->type;
  387. if(t == 0 || t == SXREF) {
  388. diag("undefined external: %s in %s",
  389. s->name, TNAME);
  390. s->type = SDATA;
  391. }
  392. instoffset = s->value + a->offset + INITDAT;
  393. if(s->type == STEXT || s->type == SLEAF || s->type == SUNDEF)
  394. instoffset = s->value + a->offset;
  395. return C_LCON;
  396. }
  397. return C_GOK;
  398. case D_FCONST:
  399. return C_FCON;
  400. case D_CONST:
  401. switch(a->name) {
  402. case D_NONE:
  403. instoffset = a->offset;
  404. if(a->reg != NREG)
  405. goto aconsize;
  406. t = immrot(instoffset);
  407. if(t)
  408. return C_RCON;
  409. t = immrot(~instoffset);
  410. if(t)
  411. return C_NCON;
  412. return C_LCON;
  413. case D_EXTERN:
  414. case D_STATIC:
  415. s = a->sym;
  416. if(s == S)
  417. break;
  418. t = s->type;
  419. switch(t) {
  420. case 0:
  421. case SXREF:
  422. diag("undefined external: %s in %s",
  423. s->name, TNAME);
  424. s->type = SDATA;
  425. break;
  426. case SUNDEF:
  427. case STEXT:
  428. case SSTRING:
  429. case SCONST:
  430. case SLEAF:
  431. instoffset = s->value + a->offset;
  432. return C_LCON;
  433. }
  434. if(!dlm) {
  435. instoffset = s->value + a->offset - BIG;
  436. t = immrot(instoffset);
  437. if(t && instoffset != 0)
  438. return C_RECON;
  439. }
  440. instoffset = s->value + a->offset + INITDAT;
  441. return C_LCON;
  442. case D_AUTO:
  443. instoffset = autosize + a->offset;
  444. goto aconsize;
  445. case D_PARAM:
  446. instoffset = autosize + a->offset + 4L;
  447. aconsize:
  448. t = immrot(instoffset);
  449. if(t)
  450. return C_RACON;
  451. return C_LACON;
  452. }
  453. return C_GOK;
  454. case D_BRANCH:
  455. return C_SBRA;
  456. }
  457. return C_GOK;
  458. }
  459. Optab*
  460. oplook(Prog *p)
  461. {
  462. int a1, a2, a3, r;
  463. char *c1, *c3;
  464. Optab *o, *e;
  465. a1 = p->optab;
  466. if(a1)
  467. return optab+(a1-1);
  468. a1 = p->from.class;
  469. if(a1 == 0) {
  470. a1 = aclass(&p->from) + 1;
  471. p->from.class = a1;
  472. }
  473. a1--;
  474. a3 = p->to.class;
  475. if(a3 == 0) {
  476. a3 = aclass(&p->to) + 1;
  477. p->to.class = a3;
  478. }
  479. a3--;
  480. a2 = C_NONE;
  481. if(p->reg != NREG)
  482. a2 = C_REG;
  483. r = p->as;
  484. o = oprange[r].start;
  485. if(o == 0) {
  486. a1 = opcross[repop[r]][a1][a2][a3];
  487. if(a1) {
  488. p->optab = a1+1;
  489. return optab+a1;
  490. }
  491. o = oprange[r].stop; /* just generate an error */
  492. }
  493. if(0) {
  494. print("oplook %A %d %d %d\n",
  495. (int)p->as, a1, a2, a3);
  496. print(" %d %d\n", p->from.type, p->to.type);
  497. }
  498. e = oprange[r].stop;
  499. c1 = xcmp[a1];
  500. c3 = xcmp[a3];
  501. for(; o<e; o++)
  502. if(o->a2 == a2)
  503. if(c1[o->a1])
  504. if(c3[o->a3]) {
  505. p->optab = (o-optab)+1;
  506. return o;
  507. }
  508. diag("illegal combination %A %d %d %d",
  509. p->as, a1, a2, a3);
  510. prasm(p);
  511. if(o == 0)
  512. o = optab;
  513. return o;
  514. }
  515. int
  516. cmp(int a, int b)
  517. {
  518. if(a == b)
  519. return 1;
  520. switch(a) {
  521. case C_LCON:
  522. if(b == C_RCON || b == C_NCON)
  523. return 1;
  524. break;
  525. case C_LACON:
  526. if(b == C_RACON)
  527. return 1;
  528. break;
  529. case C_LECON:
  530. if(b == C_RECON)
  531. return 1;
  532. break;
  533. case C_HFEXT:
  534. return b == C_HEXT || b == C_FEXT;
  535. case C_FEXT:
  536. case C_HEXT:
  537. return b == C_HFEXT;
  538. case C_SEXT:
  539. return cmp(C_HFEXT, b);
  540. case C_LEXT:
  541. return cmp(C_SEXT, b);
  542. case C_HFAUTO:
  543. return b == C_HAUTO || b == C_FAUTO;
  544. case C_FAUTO:
  545. case C_HAUTO:
  546. return b == C_HFAUTO;
  547. case C_SAUTO:
  548. return cmp(C_HFAUTO, b);
  549. case C_LAUTO:
  550. return cmp(C_SAUTO, b);
  551. case C_HFOREG:
  552. return b == C_HOREG || b == C_FOREG;
  553. case C_FOREG:
  554. case C_HOREG:
  555. return b == C_HFOREG;
  556. case C_SROREG:
  557. return cmp(C_SOREG, b) || cmp(C_ROREG, b);
  558. case C_SOREG:
  559. case C_ROREG:
  560. return b == C_SROREG || cmp(C_HFOREG, b);
  561. case C_LOREG:
  562. return cmp(C_SROREG, b);
  563. case C_LBRA:
  564. if(b == C_SBRA)
  565. return 1;
  566. break;
  567. }
  568. return 0;
  569. }
  570. int
  571. ocmp(const void *a1, const void *a2)
  572. {
  573. Optab *p1, *p2;
  574. int n;
  575. p1 = (Optab*)a1;
  576. p2 = (Optab*)a2;
  577. n = p1->as - p2->as;
  578. if(n)
  579. return n;
  580. n = (p2->flag&V4) - (p1->flag&V4); /* architecture version */
  581. if(n)
  582. return n;
  583. n = p1->a1 - p2->a1;
  584. if(n)
  585. return n;
  586. n = p1->a2 - p2->a2;
  587. if(n)
  588. return n;
  589. n = p1->a3 - p2->a3;
  590. if(n)
  591. return n;
  592. return 0;
  593. }
  594. void
  595. buildop(void)
  596. {
  597. int i, n, r;
  598. armv4 = !debug['h'];
  599. for(i=0; i<C_GOK; i++)
  600. for(n=0; n<C_GOK; n++)
  601. xcmp[i][n] = cmp(n, i);
  602. for(n=0; optab[n].as != AXXX; n++)
  603. if((optab[n].flag & V4) && !armv4) {
  604. optab[n].as = AXXX;
  605. break;
  606. }
  607. qsort(optab, n, sizeof(optab[0]), ocmp);
  608. for(i=0; i<n; i++) {
  609. r = optab[i].as;
  610. oprange[r].start = optab+i;
  611. while(optab[i].as == r)
  612. i++;
  613. oprange[r].stop = optab+i;
  614. i--;
  615. switch(r)
  616. {
  617. default:
  618. diag("unknown op in build: %A", r);
  619. errorexit();
  620. case AADD:
  621. oprange[AAND] = oprange[r];
  622. oprange[AEOR] = oprange[r];
  623. oprange[ASUB] = oprange[r];
  624. oprange[ARSB] = oprange[r];
  625. oprange[AADC] = oprange[r];
  626. oprange[ASBC] = oprange[r];
  627. oprange[ARSC] = oprange[r];
  628. oprange[AORR] = oprange[r];
  629. oprange[ABIC] = oprange[r];
  630. break;
  631. case ACMP:
  632. oprange[ATST] = oprange[r];
  633. oprange[ATEQ] = oprange[r];
  634. oprange[ACMN] = oprange[r];
  635. break;
  636. case AMVN:
  637. break;
  638. case ABEQ:
  639. oprange[ABNE] = oprange[r];
  640. oprange[ABCS] = oprange[r];
  641. oprange[ABHS] = oprange[r];
  642. oprange[ABCC] = oprange[r];
  643. oprange[ABLO] = oprange[r];
  644. oprange[ABMI] = oprange[r];
  645. oprange[ABPL] = oprange[r];
  646. oprange[ABVS] = oprange[r];
  647. oprange[ABVC] = oprange[r];
  648. oprange[ABHI] = oprange[r];
  649. oprange[ABLS] = oprange[r];
  650. oprange[ABGE] = oprange[r];
  651. oprange[ABLT] = oprange[r];
  652. oprange[ABGT] = oprange[r];
  653. oprange[ABLE] = oprange[r];
  654. break;
  655. case ASLL:
  656. oprange[ASRL] = oprange[r];
  657. oprange[ASRA] = oprange[r];
  658. break;
  659. case AMUL:
  660. oprange[AMULU] = oprange[r];
  661. break;
  662. case ADIV:
  663. oprange[AMOD] = oprange[r];
  664. oprange[AMODU] = oprange[r];
  665. oprange[ADIVU] = oprange[r];
  666. break;
  667. case AMOVW:
  668. case AMOVB:
  669. case AMOVBU:
  670. case AMOVH:
  671. case AMOVHU:
  672. break;
  673. case ASWPW:
  674. oprange[ASWPBU] = oprange[r];
  675. break;
  676. case AB:
  677. case ABL:
  678. case ABX:
  679. case ABXRET:
  680. case ASWI:
  681. case AWORD:
  682. case AMOVM:
  683. case ARFE:
  684. case ATEXT:
  685. case ACASE:
  686. case ABCASE:
  687. break;
  688. case AADDF:
  689. oprange[AADDD] = oprange[r];
  690. oprange[ASUBF] = oprange[r];
  691. oprange[ASUBD] = oprange[r];
  692. oprange[AMULF] = oprange[r];
  693. oprange[AMULD] = oprange[r];
  694. oprange[ADIVF] = oprange[r];
  695. oprange[ADIVD] = oprange[r];
  696. oprange[AMOVFD] = oprange[r];
  697. oprange[AMOVDF] = oprange[r];
  698. break;
  699. case ACMPF:
  700. oprange[ACMPD] = oprange[r];
  701. break;
  702. case AMOVF:
  703. oprange[AMOVD] = oprange[r];
  704. break;
  705. case AMOVFW:
  706. oprange[AMOVWF] = oprange[r];
  707. oprange[AMOVWD] = oprange[r];
  708. oprange[AMOVDW] = oprange[r];
  709. break;
  710. case AMULL:
  711. oprange[AMULA] = oprange[r];
  712. oprange[AMULAL] = oprange[r];
  713. oprange[AMULLU] = oprange[r];
  714. oprange[AMULALU] = oprange[r];
  715. break;
  716. }
  717. }
  718. }
  719. /*
  720. void
  721. buildrep(int x, int as)
  722. {
  723. Opcross *p;
  724. Optab *e, *s, *o;
  725. int a1, a2, a3, n;
  726. if(C_NONE != 0 || C_REG != 1 || C_GOK >= 32 || x >= nelem(opcross)) {
  727. diag("assumptions fail in buildrep");
  728. errorexit();
  729. }
  730. repop[as] = x;
  731. p = (opcross + x);
  732. s = oprange[as].start;
  733. e = oprange[as].stop;
  734. for(o=e-1; o>=s; o--) {
  735. n = o-optab;
  736. for(a2=0; a2<2; a2++) {
  737. if(a2) {
  738. if(o->a2 == C_NONE)
  739. continue;
  740. } else
  741. if(o->a2 != C_NONE)
  742. continue;
  743. for(a1=0; a1<32; a1++) {
  744. if(!xcmp[a1][o->a1])
  745. continue;
  746. for(a3=0; a3<32; a3++)
  747. if(xcmp[a3][o->a3])
  748. (*p)[a1][a2][a3] = n;
  749. }
  750. }
  751. }
  752. oprange[as].start = 0;
  753. }
  754. */
  755. enum{
  756. ABSD = 0,
  757. ABSU = 1,
  758. RELD = 2,
  759. RELU = 3,
  760. };
  761. int modemap[4] = { 0, 1, -1, 2, };
  762. typedef struct Reloc Reloc;
  763. struct Reloc
  764. {
  765. int n;
  766. int t;
  767. uchar *m;
  768. ulong *a;
  769. };
  770. Reloc rels;
  771. static void
  772. grow(Reloc *r)
  773. {
  774. int t;
  775. uchar *m, *nm;
  776. ulong *a, *na;
  777. t = r->t;
  778. r->t += 64;
  779. m = r->m;
  780. a = r->a;
  781. r->m = nm = malloc(r->t*sizeof(uchar));
  782. r->a = na = malloc(r->t*sizeof(ulong));
  783. memmove(nm, m, t*sizeof(uchar));
  784. memmove(na, a, t*sizeof(ulong));
  785. free(m);
  786. free(a);
  787. }
  788. void
  789. dynreloc(Sym *s, long v, int abs)
  790. {
  791. int i, k, n;
  792. uchar *m;
  793. ulong *a;
  794. Reloc *r;
  795. if(v&3)
  796. diag("bad relocation address");
  797. v >>= 2;
  798. if(s != S && s->type == SUNDEF)
  799. k = abs ? ABSU : RELU;
  800. else
  801. k = abs ? ABSD : RELD;
  802. /* Bprint(&bso, "R %s a=%ld(%lx) %d\n", s->name, a, a, k); */
  803. k = modemap[k];
  804. r = &rels;
  805. n = r->n;
  806. if(n >= r->t)
  807. grow(r);
  808. m = r->m;
  809. a = r->a;
  810. for(i = n; i > 0; i--){
  811. if(v < a[i-1]){ /* happens occasionally for data */
  812. m[i] = m[i-1];
  813. a[i] = a[i-1];
  814. }
  815. else
  816. break;
  817. }
  818. m[i] = k;
  819. a[i] = v;
  820. r->n++;
  821. }
  822. static int
  823. sput(char *s)
  824. {
  825. char *p;
  826. p = s;
  827. while(*s)
  828. cput(*s++);
  829. cput(0);
  830. return s-p+1;
  831. }
  832. void
  833. asmdyn()
  834. {
  835. int i, n, t, c;
  836. Sym *s;
  837. ulong la, ra, *a;
  838. vlong off;
  839. uchar *m;
  840. Reloc *r;
  841. cflush();
  842. off = seek(cout, 0, 1);
  843. lput(0);
  844. t = 0;
  845. lput(imports);
  846. t += 4;
  847. for(i = 0; i < NHASH; i++)
  848. for(s = hash[i]; s != S; s = s->link)
  849. if(s->type == SUNDEF){
  850. lput(s->sig);
  851. t += 4;
  852. t += sput(s->name);
  853. }
  854. la = 0;
  855. r = &rels;
  856. n = r->n;
  857. m = r->m;
  858. a = r->a;
  859. lput(n);
  860. t += 4;
  861. for(i = 0; i < n; i++){
  862. ra = *a-la;
  863. if(*a < la)
  864. diag("bad relocation order");
  865. if(ra < 256)
  866. c = 0;
  867. else if(ra < 65536)
  868. c = 1;
  869. else
  870. c = 2;
  871. cput((c<<6)|*m++);
  872. t++;
  873. if(c == 0){
  874. cput(ra);
  875. t++;
  876. }
  877. else if(c == 1){
  878. wput(ra);
  879. t += 2;
  880. }
  881. else{
  882. lput(ra);
  883. t += 4;
  884. }
  885. la = *a++;
  886. }
  887. cflush();
  888. seek(cout, off, 0);
  889. lput(t);
  890. if(debug['v']){
  891. Bprint(&bso, "import table entries = %d\n", imports);
  892. Bprint(&bso, "export table entries = %d\n", exports);
  893. }
  894. }