span.c 19 KB

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