span.c 17 KB

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