span.c 19 KB

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