span.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011
  1. #include "l.h"
  2. void
  3. span(void)
  4. {
  5. Prog *p, *q;
  6. Sym *setext;
  7. Optab *o;
  8. int m, bflag;
  9. vlong c, otxt;
  10. if(debug['v'])
  11. Bprint(&bso, "%5.2f span\n", cputime());
  12. Bflush(&bso);
  13. bflag = 0;
  14. c = INITTEXT;
  15. otxt = c;
  16. for(p = firstp; p != P; p = p->link) {
  17. p->pc = c;
  18. o = oplook(p);
  19. m = o->size;
  20. if(m == 0) {
  21. if(p->as == ATEXT) {
  22. curtext = p;
  23. autosize = p->to.offset + 8;
  24. if(p->from3.type == D_CONST) {
  25. if(p->from3.offset & 3)
  26. diag("illegal origin\n%P", p);
  27. if(c > p->from3.offset)
  28. diag("passed origin (#%llux)\n%P", c, p);
  29. else
  30. c = p->from3.offset;
  31. p->pc = c;
  32. }
  33. if(p->from.sym != S)
  34. p->from.sym->value = c;
  35. /* need passes to resolve branches? */
  36. if(c-otxt >= (1L<<15))
  37. bflag = c;
  38. otxt = c;
  39. continue;
  40. }
  41. if(p->as != ANOP)
  42. diag("zero-width instruction\n%P", p);
  43. continue;
  44. }
  45. c += m;
  46. }
  47. /*
  48. * if any procedure is large enough to
  49. * generate a large SBRA branch, then
  50. * generate extra passes putting branches
  51. * around jmps to fix. this is rare.
  52. */
  53. while(bflag) {
  54. if(debug['v'])
  55. Bprint(&bso, "%5.2f span1\n", cputime());
  56. bflag = 0;
  57. c = INITTEXT;
  58. for(p = firstp; p != P; p = p->link) {
  59. p->pc = c;
  60. o = oplook(p);
  61. if((o->type == 16 || o->type == 17) && p->cond) {
  62. otxt = p->cond->pc - c;
  63. if(otxt < -(1L<<16)+10 || otxt >= (1L<<15)-10) {
  64. q = prg();
  65. q->link = p->link;
  66. p->link = q;
  67. q->as = ABR;
  68. q->to.type = D_BRANCH;
  69. q->cond = p->cond;
  70. p->cond = q;
  71. q = prg();
  72. q->link = p->link;
  73. p->link = q;
  74. q->as = ABR;
  75. q->to.type = D_BRANCH;
  76. q->cond = q->link->link;
  77. addnop(p->link);
  78. addnop(p);
  79. bflag = 1;
  80. }
  81. }
  82. m = o->size;
  83. if(m == 0) {
  84. if(p->as == ATEXT) {
  85. curtext = p;
  86. autosize = p->to.offset + 8;
  87. if(p->from.sym != S)
  88. p->from.sym->value = c;
  89. continue;
  90. }
  91. if(p->as != ANOP)
  92. diag("zero-width instruction\n%P", p);
  93. continue;
  94. }
  95. c += m;
  96. }
  97. }
  98. c = rnd(c, 8);
  99. setext = lookup("etext", 0);
  100. if(setext != S) {
  101. setext->value = c;
  102. textsize = c - INITTEXT;
  103. }
  104. if(INITRND)
  105. INITDAT = rnd(c, INITRND);
  106. if(debug['v'])
  107. Bprint(&bso, "tsize = %llux\n", textsize);
  108. Bflush(&bso);
  109. }
  110. void
  111. xdefine(char *p, int t, vlong v)
  112. {
  113. Sym *s;
  114. s = lookup(p, 0);
  115. if(s->type == 0 || s->type == SXREF) {
  116. s->type = t;
  117. s->value = v;
  118. }
  119. }
  120. vlong
  121. vregoff(Adr *a)
  122. {
  123. instoffset = 0;
  124. aclass(a);
  125. return instoffset;
  126. }
  127. long
  128. regoff(Adr *a)
  129. {
  130. return vregoff(a);
  131. }
  132. int
  133. isint32(vlong v)
  134. {
  135. long l;
  136. l = v;
  137. return (vlong)l == v;
  138. }
  139. int
  140. isuint32(uvlong v)
  141. {
  142. ulong l;
  143. l = v;
  144. return (uvlong)l == v;
  145. }
  146. int
  147. aclass(Adr *a)
  148. {
  149. Sym *s;
  150. int t;
  151. switch(a->type) {
  152. case D_NONE:
  153. return C_NONE;
  154. case D_REG:
  155. return C_REG;
  156. case D_FREG:
  157. return C_FREG;
  158. case D_CREG:
  159. return C_CREG;
  160. case D_SPR:
  161. if(a->offset == D_LR)
  162. return C_LR;
  163. if(a->offset == D_XER)
  164. return C_XER;
  165. if(a->offset == D_CTR)
  166. return C_CTR;
  167. return C_SPR;
  168. case D_DCR:
  169. return C_SPR;
  170. case D_FPSCR:
  171. return C_FPSCR;
  172. case D_MSR:
  173. return C_MSR;
  174. case D_OREG:
  175. switch(a->name) {
  176. case D_EXTERN:
  177. case D_STATIC:
  178. if(a->sym == S)
  179. break;
  180. t = a->sym->type;
  181. if(t == 0 || t == SXREF) {
  182. diag("undefined external: %s in %s",
  183. a->sym->name, TNAME);
  184. a->sym->type = SDATA;
  185. }
  186. if(dlm){
  187. instoffset = a->sym->value + a->offset;
  188. switch(a->sym->type){
  189. case STEXT:
  190. case SLEAF:
  191. case SCONST:
  192. case SUNDEF:
  193. break;
  194. default:
  195. instoffset += INITDAT;
  196. }
  197. return C_ADDR;
  198. }
  199. instoffset = a->sym->value + a->offset - BIG;
  200. if(instoffset >= -BIG && instoffset < BIG)
  201. return C_SEXT;
  202. return C_LEXT;
  203. case D_AUTO:
  204. instoffset = autosize + a->offset;
  205. if(instoffset >= -BIG && instoffset < BIG)
  206. return C_SAUTO;
  207. return C_LAUTO;
  208. case D_PARAM:
  209. instoffset = autosize + a->offset + 8L;
  210. if(instoffset >= -BIG && instoffset < BIG)
  211. return C_SAUTO;
  212. return C_LAUTO;
  213. case D_NONE:
  214. instoffset = a->offset;
  215. if(instoffset == 0)
  216. return C_ZOREG;
  217. if(instoffset >= -BIG && instoffset < BIG)
  218. return C_SOREG;
  219. return C_LOREG;
  220. }
  221. return C_GOK;
  222. case D_OPT:
  223. instoffset = a->offset & 31L;
  224. if(a->name == D_NONE)
  225. return C_SCON;
  226. return C_GOK;
  227. case D_CONST:
  228. switch(a->name) {
  229. case D_NONE:
  230. instoffset = a->offset;
  231. consize:
  232. if(instoffset >= 0) {
  233. if(instoffset == 0)
  234. return C_ZCON;
  235. if(instoffset <= 0x7fff)
  236. return C_SCON;
  237. if(instoffset <= 0xffff)
  238. return C_ANDCON;
  239. if((instoffset & 0xffff) == 0 && isuint32(instoffset)) /* && (instoffset & (1<<31)) == 0) */
  240. return C_UCON;
  241. if(isint32(instoffset) || isuint32(instoffset))
  242. return C_LCON;
  243. return C_DCON;
  244. }
  245. if(instoffset >= -0x8000)
  246. return C_ADDCON;
  247. if((instoffset & 0xffff) == 0 && isint32(instoffset))
  248. return C_UCON;
  249. if(isint32(instoffset))
  250. return C_LCON;
  251. return C_DCON;
  252. case D_EXTERN:
  253. case D_STATIC:
  254. s = a->sym;
  255. if(s == S)
  256. break;
  257. t = s->type;
  258. if(t == 0 || t == SXREF) {
  259. diag("undefined external: %s in %s",
  260. s->name, TNAME);
  261. s->type = SDATA;
  262. }
  263. if(s->type == STEXT || s->type == SLEAF || s->type == SUNDEF) {
  264. instoffset = s->value + a->offset;
  265. return C_LCON;
  266. }
  267. if(s->type == SCONST) {
  268. instoffset = s->value + a->offset;
  269. if(dlm)
  270. return C_LCON;
  271. goto consize;
  272. }
  273. if(!dlm){
  274. instoffset = s->value + a->offset - BIG;
  275. if(instoffset >= -BIG && instoffset < BIG && instoffset != 0)
  276. return C_SECON;
  277. }
  278. instoffset = s->value + a->offset + INITDAT;
  279. if(dlm)
  280. return C_LCON;
  281. /* not sure why this barfs */
  282. return C_LCON;
  283. /*
  284. if(instoffset == 0)
  285. return C_ZCON;
  286. if(instoffset >= -0x8000 && instoffset <= 0xffff)
  287. return C_SCON;
  288. if((instoffset & 0xffff) == 0)
  289. return C_UCON;
  290. return C_LCON;
  291. */
  292. case D_AUTO:
  293. instoffset = autosize + a->offset;
  294. if(instoffset >= -BIG && instoffset < BIG)
  295. return C_SACON;
  296. return C_LACON;
  297. case D_PARAM:
  298. instoffset = autosize + a->offset + 8L;
  299. if(instoffset >= -BIG && instoffset < BIG)
  300. return C_SACON;
  301. return C_LACON;
  302. }
  303. return C_GOK;
  304. case D_BRANCH:
  305. return C_SBRA;
  306. }
  307. return C_GOK;
  308. }
  309. Optab*
  310. oplook(Prog *p)
  311. {
  312. int a1, a2, a3, a4, r;
  313. char *c1, *c3, *c4;
  314. Optab *o, *e;
  315. a1 = p->optab;
  316. if(a1)
  317. return optab+(a1-1);
  318. a1 = p->from.class;
  319. if(a1 == 0) {
  320. a1 = aclass(&p->from) + 1;
  321. p->from.class = a1;
  322. }
  323. a1--;
  324. a3 = p->from3.class;
  325. if(a3 == 0) {
  326. a3 = aclass(&p->from3) + 1;
  327. p->from3.class = a3;
  328. }
  329. a3--;
  330. a4 = p->to.class;
  331. if(a4 == 0) {
  332. a4 = aclass(&p->to) + 1;
  333. p->to.class = a4;
  334. }
  335. a4--;
  336. a2 = C_NONE;
  337. if(p->reg != NREG)
  338. a2 = C_REG;
  339. r = p->as;
  340. o = oprange[r].start;
  341. if(o == 0)
  342. o = oprange[r].stop; /* just generate an error */
  343. e = oprange[r].stop;
  344. c1 = xcmp[a1];
  345. c3 = xcmp[a3];
  346. c4 = xcmp[a4];
  347. for(; o<e; o++)
  348. if(o->a2 == a2)
  349. if(c1[o->a1])
  350. if(c3[o->a3])
  351. if(c4[o->a4]) {
  352. p->optab = (o-optab)+1;
  353. return o;
  354. }
  355. diag("illegal combination %A %R %R %R %R",
  356. p->as, a1, a2, a3, a4);
  357. if(1||!debug['a'])
  358. prasm(p);
  359. if(o == 0)
  360. errorexit();
  361. return o;
  362. }
  363. int
  364. cmp(int a, int b)
  365. {
  366. if(a == b)
  367. return 1;
  368. switch(a) {
  369. case C_LCON:
  370. if(b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON)
  371. return 1;
  372. break;
  373. case C_ADDCON:
  374. if(b == C_ZCON || b == C_SCON)
  375. return 1;
  376. break;
  377. case C_ANDCON:
  378. if(b == C_ZCON || b == C_SCON)
  379. return 1;
  380. break;
  381. case C_SPR:
  382. if(b == C_LR || b == C_XER || b == C_CTR)
  383. return 1;
  384. break;
  385. case C_UCON:
  386. if(b == C_ZCON)
  387. return 1;
  388. break;
  389. case C_SCON:
  390. if(b == C_ZCON)
  391. return 1;
  392. break;
  393. case C_LACON:
  394. if(b == C_SACON)
  395. return 1;
  396. break;
  397. case C_LBRA:
  398. if(b == C_SBRA)
  399. return 1;
  400. break;
  401. case C_LEXT:
  402. if(b == C_SEXT)
  403. return 1;
  404. break;
  405. case C_LAUTO:
  406. if(b == C_SAUTO)
  407. return 1;
  408. break;
  409. case C_REG:
  410. if(b == C_ZCON)
  411. return r0iszero;
  412. break;
  413. case C_LOREG:
  414. if(b == C_ZOREG || b == C_SOREG)
  415. return 1;
  416. break;
  417. case C_SOREG:
  418. if(b == C_ZOREG)
  419. return 1;
  420. break;
  421. case C_ANY:
  422. return 1;
  423. }
  424. return 0;
  425. }
  426. int
  427. ocmp(void *a1, void *a2)
  428. {
  429. Optab *p1, *p2;
  430. int n;
  431. p1 = a1;
  432. p2 = a2;
  433. n = p1->as - p2->as;
  434. if(n)
  435. return n;
  436. n = p1->a1 - p2->a1;
  437. if(n)
  438. return n;
  439. n = p1->a2 - p2->a2;
  440. if(n)
  441. return n;
  442. n = p1->a3 - p2->a3;
  443. if(n)
  444. return n;
  445. n = p1->a4 - p2->a4;
  446. if(n)
  447. return n;
  448. return 0;
  449. }
  450. void
  451. buildop(void)
  452. {
  453. int i, n, r;
  454. for(i=0; i<C_NCLASS; i++)
  455. for(n=0; n<C_NCLASS; n++)
  456. xcmp[i][n] = cmp(n, i);
  457. for(n=0; optab[n].as != AXXX; n++)
  458. ;
  459. qsort(optab, n, sizeof(optab[0]), ocmp);
  460. for(i=0; i<n; i++) {
  461. r = optab[i].as;
  462. oprange[r].start = optab+i;
  463. while(optab[i].as == r)
  464. i++;
  465. oprange[r].stop = optab+i;
  466. i--;
  467. switch(r)
  468. {
  469. default:
  470. diag("unknown op in build: %A", r);
  471. errorexit();
  472. case ADCBF: /* unary indexed: op (b+a); op (b) */
  473. oprange[ADCBI] = oprange[r];
  474. oprange[ADCBST] = oprange[r];
  475. oprange[ADCBT] = oprange[r];
  476. oprange[ADCBTST] = oprange[r];
  477. oprange[ADCBZ] = oprange[r];
  478. oprange[AICBI] = oprange[r];
  479. break;
  480. case AECOWX: /* indexed store: op s,(b+a); op s,(b) */
  481. oprange[ASTWCCC] = oprange[r];
  482. break;
  483. case AREM: /* macro */
  484. oprange[AREMCC] = oprange[r];
  485. oprange[AREMV] = oprange[r];
  486. oprange[AREMVCC] = oprange[r];
  487. oprange[AREMU] = oprange[r];
  488. oprange[AREMUCC] = oprange[r];
  489. oprange[AREMUV] = oprange[r];
  490. oprange[AREMUVCC] = oprange[r];
  491. break;
  492. case AREMD:
  493. oprange[AREMDCC] = oprange[r];
  494. oprange[AREMDV] = oprange[r];
  495. oprange[AREMDVCC] = oprange[r];
  496. oprange[AREMDU] = oprange[r];
  497. oprange[AREMDUCC] = oprange[r];
  498. oprange[AREMDUV] = oprange[r];
  499. oprange[AREMDUVCC] = oprange[r];
  500. break;
  501. case ADIVW: /* op Rb[,Ra],Rd */
  502. oprange[AMULHW] = oprange[r];
  503. oprange[AMULHWCC] = oprange[r];
  504. oprange[AMULHWU] = oprange[r];
  505. oprange[AMULHWUCC] = oprange[r];
  506. oprange[AMULLWCC] = oprange[r];
  507. oprange[AMULLWVCC] = oprange[r];
  508. oprange[AMULLWV] = oprange[r];
  509. oprange[ADIVWCC] = oprange[r];
  510. oprange[ADIVWV] = oprange[r];
  511. oprange[ADIVWVCC] = oprange[r];
  512. oprange[ADIVWU] = oprange[r];
  513. oprange[ADIVWUCC] = oprange[r];
  514. oprange[ADIVWUV] = oprange[r];
  515. oprange[ADIVWUVCC] = oprange[r];
  516. oprange[AADDCC] = oprange[r];
  517. oprange[AADDCV] = oprange[r];
  518. oprange[AADDCVCC] = oprange[r];
  519. oprange[AADDV] = oprange[r];
  520. oprange[AADDVCC] = oprange[r];
  521. oprange[AADDE] = oprange[r];
  522. oprange[AADDECC] = oprange[r];
  523. oprange[AADDEV] = oprange[r];
  524. oprange[AADDEVCC] = oprange[r];
  525. oprange[ACRAND] = oprange[r];
  526. oprange[ACRANDN] = oprange[r];
  527. oprange[ACREQV] = oprange[r];
  528. oprange[ACRNAND] = oprange[r];
  529. oprange[ACRNOR] = oprange[r];
  530. oprange[ACROR] = oprange[r];
  531. oprange[ACRORN] = oprange[r];
  532. oprange[ACRXOR] = oprange[r];
  533. oprange[AMULHD] = oprange[r];
  534. oprange[AMULHDCC] = oprange[r];
  535. oprange[AMULHDU] = oprange[r];
  536. oprange[AMULHDUCC] = oprange[r];
  537. oprange[AMULLD] = oprange[r];
  538. oprange[AMULLDCC] = oprange[r];
  539. oprange[AMULLDVCC] = oprange[r];
  540. oprange[AMULLDV] = oprange[r];
  541. oprange[ADIVD] = oprange[r];
  542. oprange[ADIVDCC] = oprange[r];
  543. oprange[ADIVDVCC] = oprange[r];
  544. oprange[ADIVDV] = oprange[r];
  545. oprange[ADIVDU] = oprange[r];
  546. oprange[ADIVDUCC] = oprange[r];
  547. oprange[ADIVDUVCC] = oprange[r];
  548. oprange[ADIVDUCC] = oprange[r];
  549. break;
  550. case AMOVBZ: /* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */
  551. oprange[AMOVH] = oprange[r];
  552. oprange[AMOVHZ] = oprange[r];
  553. break;
  554. case AMOVBZU: /* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x, ld[x]u, std[u]x */
  555. oprange[AMOVHU] = oprange[r];
  556. oprange[AMOVHZU] = oprange[r];
  557. oprange[AMOVWU] = oprange[r];
  558. oprange[AMOVWZU] = oprange[r];
  559. oprange[AMOVDU] = oprange[r];
  560. oprange[AMOVMW] = oprange[r];
  561. break;
  562. case AAND: /* logical op Rb,Rs,Ra; no literal */
  563. oprange[AANDN] = oprange[r];
  564. oprange[AANDNCC] = oprange[r];
  565. oprange[AEQV] = oprange[r];
  566. oprange[AEQVCC] = oprange[r];
  567. oprange[ANAND] = oprange[r];
  568. oprange[ANANDCC] = oprange[r];
  569. oprange[ANOR] = oprange[r];
  570. oprange[ANORCC] = oprange[r];
  571. oprange[AORCC] = oprange[r];
  572. oprange[AORN] = oprange[r];
  573. oprange[AORNCC] = oprange[r];
  574. oprange[AXORCC] = oprange[r];
  575. break;
  576. case AADDME: /* op Ra, Rd */
  577. oprange[AADDMECC] = oprange[r];
  578. oprange[AADDMEV] = oprange[r];
  579. oprange[AADDMEVCC] = oprange[r];
  580. oprange[AADDZE] = oprange[r];
  581. oprange[AADDZECC] = oprange[r];
  582. oprange[AADDZEV] = oprange[r];
  583. oprange[AADDZEVCC] = oprange[r];
  584. oprange[ASUBME] = oprange[r];
  585. oprange[ASUBMECC] = oprange[r];
  586. oprange[ASUBMEV] = oprange[r];
  587. oprange[ASUBMEVCC] = oprange[r];
  588. oprange[ASUBZE] = oprange[r];
  589. oprange[ASUBZECC] = oprange[r];
  590. oprange[ASUBZEV] = oprange[r];
  591. oprange[ASUBZEVCC] = oprange[r];
  592. break;
  593. case AADDC:
  594. oprange[AADDCCC] = oprange[r];
  595. break;
  596. case ABEQ:
  597. oprange[ABGE] = oprange[r];
  598. oprange[ABGT] = oprange[r];
  599. oprange[ABLE] = oprange[r];
  600. oprange[ABLT] = oprange[r];
  601. oprange[ABNE] = oprange[r];
  602. oprange[ABVC] = oprange[r];
  603. oprange[ABVS] = oprange[r];
  604. break;
  605. case ABR:
  606. oprange[ABL] = oprange[r];
  607. break;
  608. case ABC:
  609. oprange[ABCL] = oprange[r];
  610. break;
  611. case AEXTSB: /* op Rs, Ra */
  612. oprange[AEXTSBCC] = oprange[r];
  613. oprange[AEXTSH] = oprange[r];
  614. oprange[AEXTSHCC] = oprange[r];
  615. oprange[ACNTLZW] = oprange[r];
  616. oprange[ACNTLZWCC] = oprange[r];
  617. oprange[ACNTLZD] = oprange[r];
  618. oprange[AEXTSW] = oprange[r];
  619. oprange[AEXTSWCC] = oprange[r];
  620. oprange[ACNTLZDCC] = oprange[r];
  621. break;
  622. case AFABS: /* fop [s,]d */
  623. oprange[AFABSCC] = oprange[r];
  624. oprange[AFNABS] = oprange[r];
  625. oprange[AFNABSCC] = oprange[r];
  626. oprange[AFNEG] = oprange[r];
  627. oprange[AFNEGCC] = oprange[r];
  628. oprange[AFRSP] = oprange[r];
  629. oprange[AFRSPCC] = oprange[r];
  630. oprange[AFCTIW] = oprange[r];
  631. oprange[AFCTIWCC] = oprange[r];
  632. oprange[AFCTIWZ] = oprange[r];
  633. oprange[AFCTIWZCC] = oprange[r];
  634. oprange[AFCTID] = oprange[r];
  635. oprange[AFCTIDCC] = oprange[r];
  636. oprange[AFCTIDZ] = oprange[r];
  637. oprange[AFCTIDZCC] = oprange[r];
  638. oprange[AFCFID] = oprange[r];
  639. oprange[AFCFIDCC] = oprange[r];
  640. oprange[AFRES] = oprange[r];
  641. oprange[AFRESCC] = oprange[r];
  642. oprange[AFRSQRTE] = oprange[r];
  643. oprange[AFRSQRTECC] = oprange[r];
  644. oprange[AFSQRT] = oprange[r];
  645. oprange[AFSQRTCC] = oprange[r];
  646. oprange[AFSQRTS] = oprange[r];
  647. oprange[AFSQRTSCC] = oprange[r];
  648. break;
  649. case AFADD:
  650. oprange[AFADDS] = oprange[r];
  651. oprange[AFADDCC] = oprange[r];
  652. oprange[AFADDSCC] = oprange[r];
  653. oprange[AFDIV] = oprange[r];
  654. oprange[AFDIVS] = oprange[r];
  655. oprange[AFDIVCC] = oprange[r];
  656. oprange[AFDIVSCC] = oprange[r];
  657. oprange[AFSUB] = oprange[r];
  658. oprange[AFSUBS] = oprange[r];
  659. oprange[AFSUBCC] = oprange[r];
  660. oprange[AFSUBSCC] = oprange[r];
  661. break;
  662. case AFMADD:
  663. oprange[AFMADDCC] = oprange[r];
  664. oprange[AFMADDS] = oprange[r];
  665. oprange[AFMADDSCC] = oprange[r];
  666. oprange[AFMSUB] = oprange[r];
  667. oprange[AFMSUBCC] = oprange[r];
  668. oprange[AFMSUBS] = oprange[r];
  669. oprange[AFMSUBSCC] = oprange[r];
  670. oprange[AFNMADD] = oprange[r];
  671. oprange[AFNMADDCC] = oprange[r];
  672. oprange[AFNMADDS] = oprange[r];
  673. oprange[AFNMADDSCC] = oprange[r];
  674. oprange[AFNMSUB] = oprange[r];
  675. oprange[AFNMSUBCC] = oprange[r];
  676. oprange[AFNMSUBS] = oprange[r];
  677. oprange[AFNMSUBSCC] = oprange[r];
  678. oprange[AFSEL] = oprange[r];
  679. oprange[AFSELCC] = oprange[r];
  680. break;
  681. case AFMUL:
  682. oprange[AFMULS] = oprange[r];
  683. oprange[AFMULCC] = oprange[r];
  684. oprange[AFMULSCC] = oprange[r];
  685. break;
  686. case AFCMPO:
  687. oprange[AFCMPU] = oprange[r];
  688. break;
  689. case AMTFSB0:
  690. oprange[AMTFSB0CC] = oprange[r];
  691. oprange[AMTFSB1] = oprange[r];
  692. oprange[AMTFSB1CC] = oprange[r];
  693. break;
  694. case ANEG: /* op [Ra,] Rd */
  695. oprange[ANEGCC] = oprange[r];
  696. oprange[ANEGV] = oprange[r];
  697. oprange[ANEGVCC] = oprange[r];
  698. break;
  699. case AOR: /* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,Ra; oris/xoris $uimm,Rs,Ra */
  700. oprange[AXOR] = oprange[r];
  701. break;
  702. case ASLW:
  703. oprange[ASLWCC] = oprange[r];
  704. oprange[ASRW] = oprange[r];
  705. oprange[ASRWCC] = oprange[r];
  706. break;
  707. case ASLD:
  708. oprange[ASLDCC] = oprange[r];
  709. oprange[ASRD] = oprange[r];
  710. oprange[ASRDCC] = oprange[r];
  711. break;
  712. case ASRAW: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
  713. oprange[ASRAWCC] = oprange[r];
  714. break;
  715. case ASRAD: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
  716. oprange[ASRADCC] = oprange[r];
  717. break;
  718. case ASUB: /* SUB Ra,Rb,Rd => subf Rd,ra,rb */
  719. oprange[ASUB] = oprange[r];
  720. oprange[ASUBCC] = oprange[r];
  721. oprange[ASUBV] = oprange[r];
  722. oprange[ASUBVCC] = oprange[r];
  723. oprange[ASUBCCC] = oprange[r];
  724. oprange[ASUBCV] = oprange[r];
  725. oprange[ASUBCVCC] = oprange[r];
  726. oprange[ASUBE] = oprange[r];
  727. oprange[ASUBECC] = oprange[r];
  728. oprange[ASUBEV] = oprange[r];
  729. oprange[ASUBEVCC] = oprange[r];
  730. break;
  731. case ASYNC:
  732. oprange[AISYNC] = oprange[r];
  733. oprange[APTESYNC] = oprange[r];
  734. oprange[ATLBSYNC] = oprange[r];
  735. break;
  736. case ARLWMI:
  737. oprange[ARLWMICC] = oprange[r];
  738. oprange[ARLWNM] = oprange[r];
  739. oprange[ARLWNMCC] = oprange[r];
  740. break;
  741. case ARLDMI:
  742. oprange[ARLDMICC] = oprange[r];
  743. break;
  744. case ARLDC:
  745. oprange[ARLDCCC] = oprange[r];
  746. break;
  747. case ARLDCL:
  748. oprange[ARLDCR] = oprange[r];
  749. oprange[ARLDCLCC] = oprange[r];
  750. oprange[ARLDCRCC] = oprange[r];
  751. break;
  752. case AFMOVD:
  753. oprange[AFMOVDCC] = oprange[r];
  754. oprange[AFMOVDU] = oprange[r];
  755. oprange[AFMOVS] = oprange[r];
  756. oprange[AFMOVSU] = oprange[r];
  757. break;
  758. case AECIWX:
  759. oprange[ALWAR] = oprange[r];
  760. break;
  761. case ASYSCALL: /* just the op; flow of control */
  762. oprange[ARFI] = oprange[r];
  763. oprange[ARFCI] = oprange[r];
  764. oprange[ARFID] = oprange[r];
  765. oprange[AHRFID] = oprange[r];
  766. break;
  767. case AMOVHBR:
  768. oprange[AMOVWBR] = oprange[r];
  769. break;
  770. case ASLBMFEE:
  771. oprange[ASLBMFEV] = oprange[r];
  772. break;
  773. case ATW:
  774. oprange[ATD] = oprange[r];
  775. break;
  776. case ATLBIE:
  777. oprange[ASLBIE] = oprange[r];
  778. oprange[ATLBIEL] = oprange[r];
  779. break;
  780. case AEIEIO:
  781. oprange[ASLBIA] = oprange[r];
  782. break;
  783. case ACMP:
  784. oprange[ACMPW] = oprange[r];
  785. break;
  786. case ACMPU:
  787. oprange[ACMPWU] = oprange[r];
  788. break;
  789. case AADD:
  790. case AANDCC: /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra; andis. $uimm,Rs,Ra */
  791. case ALSW:
  792. case AMOVW: /* load/store/move word with sign extension; special 32-bit move; move 32-bit literals */
  793. case AMOVWZ: /* load/store/move word with zero extension; move 32-bit literals */
  794. case AMOVD: /* load/store/move 64-bit values, including 32-bit literals with/without sign-extension */
  795. case AMOVB: /* macro: move byte with sign extension */
  796. case AMOVBU: /* macro: move byte with sign extension & update */
  797. case AMOVFL:
  798. case AMULLW: /* op $s[,r2],r3; op r1[,r2],r3; no cc/v */
  799. case ASUBC: /* op r1,$s,r3; op r1[,r2],r3 */
  800. case ASTSW:
  801. case ASLBMTE:
  802. case AWORD:
  803. case ADWORD:
  804. case ANOP:
  805. case ATEXT:
  806. break;
  807. }
  808. }
  809. }
  810. enum{
  811. ABSD = 0,
  812. ABSU = 1,
  813. RELD = 2,
  814. RELU = 3,
  815. };
  816. int modemap[8] = { 0, 1, -1, 2, 3, 4, 5, 6};
  817. typedef struct Reloc Reloc;
  818. struct Reloc
  819. {
  820. int n;
  821. int t;
  822. uchar *m;
  823. ulong *a;
  824. };
  825. Reloc rels;
  826. static void
  827. grow(Reloc *r)
  828. {
  829. int t;
  830. uchar *m, *nm;
  831. ulong *a, *na;
  832. t = r->t;
  833. r->t += 64;
  834. m = r->m;
  835. a = r->a;
  836. r->m = nm = malloc(r->t*sizeof(uchar));
  837. r->a = na = malloc(r->t*sizeof(ulong));
  838. memmove(nm, m, t*sizeof(uchar));
  839. memmove(na, a, t*sizeof(ulong));
  840. free(m);
  841. free(a);
  842. }
  843. void
  844. dynreloc(Sym *s, long v, int abs, int split, int sext)
  845. {
  846. int i, k, n;
  847. uchar *m;
  848. ulong *a;
  849. Reloc *r;
  850. if(v&3)
  851. diag("bad relocation address");
  852. v >>= 2;
  853. if(s->type == SUNDEF)
  854. k = abs ? ABSU : RELU;
  855. else
  856. k = abs ? ABSD : RELD;
  857. if(split)
  858. k += 4;
  859. if(sext)
  860. k += 2;
  861. /* Bprint(&bso, "R %s a=%ld(%lx) %d\n", s->name, a, a, k); */
  862. k = modemap[k];
  863. r = &rels;
  864. n = r->n;
  865. if(n >= r->t)
  866. grow(r);
  867. m = r->m;
  868. a = r->a;
  869. for(i = n; i > 0; i--){
  870. if(v < a[i-1]){ /* happens occasionally for data */
  871. m[i] = m[i-1];
  872. a[i] = a[i-1];
  873. }
  874. else
  875. break;
  876. }
  877. m[i] = k;
  878. a[i] = v;
  879. r->n++;
  880. }
  881. static int
  882. sput(char *s)
  883. {
  884. char *p;
  885. p = s;
  886. while(*s)
  887. cput(*s++);
  888. cput(0);
  889. return s-p+1;
  890. }
  891. void
  892. asmdyn()
  893. {
  894. int i, n, t, c;
  895. Sym *s;
  896. ulong la, ra, *a;
  897. vlong off;
  898. uchar *m;
  899. Reloc *r;
  900. cflush();
  901. off = seek(cout, 0, 1);
  902. lput(0);
  903. t = 0;
  904. lput(imports);
  905. t += 4;
  906. for(i = 0; i < NHASH; i++)
  907. for(s = hash[i]; s != S; s = s->link)
  908. if(s->type == SUNDEF){
  909. lput(s->sig);
  910. t += 4;
  911. t += sput(s->name);
  912. }
  913. la = 0;
  914. r = &rels;
  915. n = r->n;
  916. m = r->m;
  917. a = r->a;
  918. lput(n);
  919. t += 4;
  920. for(i = 0; i < n; i++){
  921. ra = *a-la;
  922. if(*a < la)
  923. diag("bad relocation order");
  924. if(ra < 256)
  925. c = 0;
  926. else if(ra < 65536)
  927. c = 1;
  928. else
  929. c = 2;
  930. cput((c<<6)|*m++);
  931. t++;
  932. if(c == 0){
  933. cput(ra);
  934. t++;
  935. }
  936. else if(c == 1){
  937. wput(ra);
  938. t += 2;
  939. }
  940. else{
  941. lput(ra);
  942. t += 4;
  943. }
  944. la = *a++;
  945. }
  946. cflush();
  947. seek(cout, off, 0);
  948. lput(t);
  949. if(debug['v']){
  950. Bprint(&bso, "import table entries = %d\n", imports);
  951. Bprint(&bso, "export table entries = %d\n", exports);
  952. }
  953. }