peep.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059
  1. #include "gc.h"
  2. void
  3. peep(void)
  4. {
  5. Reg *r, *r1, *r2;
  6. Prog *p, *p1;
  7. int t, s;
  8. /*
  9. * complete R structure
  10. */
  11. t = 0;
  12. for(r=firstr; r!=R; r=r1) {
  13. r1 = r->link;
  14. if(r1 == R)
  15. break;
  16. p = r->prog->link;
  17. while(p != r1->prog)
  18. switch(p->as) {
  19. default:
  20. r2 = rega();
  21. r->link = r2;
  22. r2->link = r1;
  23. r2->prog = p;
  24. r2->p1 = r;
  25. r->s1 = r2;
  26. r2->s1 = r1;
  27. r1->p1 = r2;
  28. r = r2;
  29. t++;
  30. case ADATA:
  31. case AGLOBL:
  32. case ANAME:
  33. p = p->link;
  34. }
  35. }
  36. loop1:
  37. /*
  38. * propigate move's by renaming
  39. */
  40. t = 0;
  41. for(r=firstr; r!=R; r=r->link) {
  42. p = r->prog;
  43. if(p->as == AMOVL || p->as == AFMOVEF || p->as == AFMOVED)
  44. if(regtyp(p->from.type))
  45. if(anyvar(&p->to)) {
  46. if(copyprop(r)) {
  47. excise(r);
  48. t++;
  49. } else
  50. if(subprop(r) && copyprop(r)) {
  51. excise(r);
  52. t++;
  53. }
  54. }
  55. }
  56. if(t)
  57. goto loop1;
  58. for(r=firstr; r!=R; r=r->link) {
  59. p = r->prog;
  60. /*
  61. * convert (A) ... A++ into (A)++
  62. * and A-- ... (A) into --(A)
  63. */
  64. t = aregind(&p->from);
  65. if(t == D_NONE)
  66. goto out1;
  67. s = asize(p->as);
  68. if(s == 0)
  69. goto out1;
  70. r1 = findop(r, t, AADDL, s);
  71. if(r1 != R) {
  72. if(usedin(t, &p->to))
  73. goto out1;
  74. p->from.type += I_INDINC - I_INDIR;
  75. excise(r1);
  76. goto out1;
  77. }
  78. r1 = findop(r, t, ASUBL, s);
  79. if(r1 != R) {
  80. p->from.type += I_INDDEC - I_INDIR;
  81. excise(r1);
  82. }
  83. out1:
  84. t = aregind(&p->to);
  85. if(t == D_NONE)
  86. goto out2;
  87. s = asize(p->as);
  88. if(s == 0)
  89. goto out2;
  90. r1 = findop(r, t, AADDL, s);
  91. if(r1 != R) {
  92. p->to.type += I_INDINC - I_INDIR;
  93. excise(r1);
  94. goto out2;
  95. }
  96. r1 = findop(r, t, ASUBL, s);
  97. if(r1 != R) {
  98. if(usedin(t, &p->from))
  99. goto out2;
  100. p->to.type += I_INDDEC - I_INDIR;
  101. excise(r1);
  102. }
  103. out2:
  104. /*
  105. * get rid of unneeded save/restore CCR
  106. */
  107. if(p->from.type == D_CCR) {
  108. r1 = findccr(r);
  109. if(r1 != R) {
  110. excise(r);
  111. excise(r1);
  112. }
  113. }
  114. switch(p->as) {
  115. case ATSTB:
  116. case ATSTW:
  117. case ATSTL:
  118. if(findtst(r, r->prog, 0))
  119. excise(r);
  120. }
  121. /*
  122. * turn TSTB (A); BLT; ORB $128,(A) into TAS (A); BLT; NOP
  123. */
  124. if(p->as == ATSTB && (r1 = r->s1)) {
  125. if((r1->prog->as == ABLT && (r2 = r1->s1)) ||
  126. (r1->prog->as == ABGE && (r2 = r1->s2))) {
  127. p1 = r2->prog;
  128. if(p1->as == AORB)
  129. if(p1->from.type == D_CONST)
  130. if(p1->from.offset == 128)
  131. if(r1 == uniqp(r2))
  132. if(tasas(&p->to, &p1->to)) {
  133. p->as = ATAS;
  134. excise(r2);
  135. }
  136. }
  137. }
  138. }
  139. }
  140. void
  141. excise(Reg *r)
  142. {
  143. p = r->prog;
  144. p->as = ANOP;
  145. p->from = zprog.from;
  146. p->to = zprog.to;
  147. }
  148. Reg*
  149. uniqp(Reg *r)
  150. {
  151. Reg *r1;
  152. r1 = r->p1;
  153. if(r1 == R) {
  154. r1 = r->p2;
  155. if(r1 == R || r1->p2link != R)
  156. return R;
  157. } else
  158. if(r->p2 != R)
  159. return R;
  160. return r1;
  161. }
  162. Reg*
  163. uniqs(Reg *r)
  164. {
  165. Reg *r1;
  166. r1 = r->s1;
  167. if(r1 == R) {
  168. r1 = r->s2;
  169. if(r1 == R)
  170. return R;
  171. } else
  172. if(r->s2 != R)
  173. return R;
  174. return r1;
  175. }
  176. /*
  177. * chase backward all cc setting.
  178. * returns 1 if all set same.
  179. */
  180. int
  181. findtst(Reg *r0, Prog *rp, int n)
  182. {
  183. Reg *r;
  184. int c;
  185. loop:
  186. n++;
  187. if(n >= 10)
  188. return 0;
  189. for(r=r0->p2; r!=R; r=r->p2link) {
  190. c = setcc(r->prog, rp);
  191. if(c > 0)
  192. continue;
  193. if(c == 0)
  194. return 0;
  195. if(findtst(r, rp, n) == 0)
  196. return 0;
  197. }
  198. r = r0->p1;
  199. if(r == R)
  200. return 1;
  201. c = setcc(r->prog, rp);
  202. if(c > 0)
  203. return 1;
  204. if(c == 0)
  205. return 0;
  206. r0 = r;
  207. goto loop;
  208. }
  209. /*
  210. * tests cc
  211. * returns -1 if no change
  212. * returns 1 if set the same
  213. * returns 0 if set different
  214. */
  215. int
  216. setcc(Prog *p, Prog *rp)
  217. {
  218. int s;
  219. s = asize(rp->as);
  220. switch(p->as) {
  221. default:
  222. if(debug['P'])
  223. print("unknown setcc %A\n", p->as);
  224. break;
  225. case ACMPB:
  226. case ACMPW:
  227. case ACMPL:
  228. case ABSR:
  229. return 0;
  230. case ABRA:
  231. case ABGE:
  232. case ABNE:
  233. case ABLE:
  234. case ABEQ:
  235. case ABHI:
  236. case ABLS:
  237. case ABMI:
  238. case ABPL:
  239. case ABGT:
  240. case ABLT:
  241. case ABCC:
  242. case ABCS:
  243. case APEA:
  244. case ALEA:
  245. case ANOP:
  246. case AFADDD:
  247. case AFMULD:
  248. case AFDIVD:
  249. case AFSUBD:
  250. case AFADDF:
  251. case AFMULF:
  252. case AFDIVF:
  253. case AFSUBF:
  254. case AADJSP:
  255. return -1;
  256. case AADDW:
  257. case AADDL:
  258. case ASUBW:
  259. case ASUBL:
  260. case ACLRL:
  261. case ACLRW:
  262. if(p->to.type >= D_A0 && p->to.type < D_A0+8)
  263. goto areg;
  264. case AADDB:
  265. case ASUBB:
  266. case AANDB:
  267. case AANDW:
  268. case AANDL:
  269. case AORB:
  270. case AORW:
  271. case AORL:
  272. case AEORB:
  273. case AEORW:
  274. case AEORL:
  275. case ALSLB:
  276. case ALSLW:
  277. case ALSLL:
  278. case ALSRB:
  279. case ALSRW:
  280. case ALSRL:
  281. case AASLB:
  282. case AASLW:
  283. case AASLL:
  284. case AASRB:
  285. case AASRW:
  286. case AASRL:
  287. case ATSTB:
  288. case ATSTW:
  289. case ATSTL:
  290. case ANEGB:
  291. case ANEGW:
  292. case ANEGL:
  293. case ACLRB:
  294. if(asize(p->as) != s)
  295. break;
  296. if(compat(&rp->to, &p->to))
  297. return 1;
  298. break;
  299. case AMOVW:
  300. case AMOVL:
  301. if(p->to.type >= D_A0 && p->to.type < D_A0+8)
  302. goto areg;
  303. case AMOVB:
  304. if(asize(p->as) != s)
  305. break;
  306. if(compat(&rp->to, &p->to))
  307. return 1;
  308. if(compat(&rp->to, &p->from))
  309. return 1;
  310. }
  311. return 0;
  312. areg:
  313. if((rp->to.type&D_MASK) == p->to.type)
  314. return 0;
  315. return -1;
  316. }
  317. int
  318. compat(Adr *a, Adr *b)
  319. {
  320. int o;
  321. o = a->type;
  322. if((o >= D_R0 && o < D_R0+NREG) ||
  323. (o >= D_A0 && o < D_A0+NREG))
  324. return o == b->type;
  325. o &= D_MASK;
  326. if(o >= D_A0 && o < D_A0+NREG) {
  327. if(o != (b->type&D_MASK))
  328. return 0;
  329. if(a->offset != b->offset)
  330. return 0;
  331. o = a->type & I_MASK;
  332. if(o == I_INDIR) {
  333. o = b->type & I_MASK;
  334. if(o == I_INDIR || o == I_INDDEC)
  335. return 1;
  336. return 0;
  337. }
  338. if(o == I_INDINC) {
  339. o = b->type & I_MASK;
  340. if(o == I_INDIR) {
  341. b->type += I_INDINC-I_INDIR;
  342. return 1;
  343. }
  344. if(o == I_INDDEC) {
  345. b->type += I_INDIR-I_INDDEC;
  346. return 1;
  347. }
  348. return 0;
  349. }
  350. }
  351. return 0;
  352. }
  353. int
  354. aregind(Adr *a)
  355. {
  356. int t;
  357. t = a->type;
  358. if(t >= (D_A0|I_INDIR) && t < ((D_A0+NREG)|I_INDIR))
  359. while(a->offset == 0)
  360. return t & D_MASK;
  361. return D_NONE;
  362. }
  363. int
  364. asize(int a)
  365. {
  366. switch(a) {
  367. case AFTSTD:
  368. case AFMOVED:
  369. case AFADDD:
  370. case AFSUBD:
  371. case AFMULD:
  372. case AFDIVD:
  373. case AFCMPD:
  374. case AFNEGD:
  375. return 8;
  376. case AFTSTF:
  377. case AFMOVEF:
  378. case AFADDF:
  379. case AFSUBF:
  380. case AFMULF:
  381. case AFDIVF:
  382. case AFCMPF:
  383. case AFNEGF:
  384. case ACLRL:
  385. case ATSTL:
  386. case AMOVL:
  387. case AADDL:
  388. case ASUBL:
  389. case ACMPL:
  390. case AANDL:
  391. case AORL:
  392. case AEORL:
  393. case ALSLL:
  394. case ALSRL:
  395. case AASLL:
  396. case AASRL:
  397. case ANEGL:
  398. return 4;
  399. case ACLRW:
  400. case ATSTW:
  401. case AMOVW:
  402. case AADDW:
  403. case ASUBW:
  404. case ACMPW:
  405. case AANDW:
  406. case AORW:
  407. case AEORW:
  408. case ALSLW:
  409. case ALSRW:
  410. case AASLW:
  411. case AASRW:
  412. case ANEGW:
  413. return 2;
  414. case ACLRB:
  415. case ATSTB:
  416. case AMOVB:
  417. case AADDB:
  418. case ASUBB:
  419. case ACMPB:
  420. case AANDB:
  421. case AORB:
  422. case AEORB:
  423. case ALSLB:
  424. case ALSRB:
  425. case AASLB:
  426. case AASRB:
  427. case ANEGB:
  428. return 1;
  429. }
  430. if(debug['P'])
  431. print("unknown asize %A\n", p->as);
  432. return 0;
  433. }
  434. int
  435. usedin(int t, Adr *a)
  436. {
  437. if((a->type&D_MASK) == t)
  438. return 1;
  439. return 0;
  440. }
  441. Reg*
  442. findccr(Reg *r)
  443. {
  444. Prog *p;
  445. for(;;) {
  446. r = uniqs(r);
  447. if(r == R)
  448. break;
  449. p = r->prog;
  450. if(p->to.type == D_CCR)
  451. return r;
  452. if(setccr(p))
  453. break;
  454. }
  455. return R;
  456. }
  457. int
  458. setccr(Prog *p)
  459. {
  460. switch(p->as) {
  461. case ANOP:
  462. return 0;
  463. case AADDL:
  464. case AMOVL:
  465. case ACLRL:
  466. if(p->to.type >= D_A0 && p->to.type < D_A0+8)
  467. return 0;
  468. }
  469. return 1;
  470. }
  471. Reg*
  472. findop(Reg *r, int t, int o, int s)
  473. {
  474. Prog *p;
  475. Reg *r1;
  476. for(;;) {
  477. if(o == AADDL) {
  478. r1 = uniqs(r);
  479. if(r1 == R)
  480. break;
  481. if(uniqp(r1) != r)
  482. break;
  483. } else {
  484. r1 = uniqp(r);
  485. if(r1 == R)
  486. break;
  487. if(uniqs(r1) != r)
  488. break;
  489. }
  490. r = r1;
  491. p = r->prog;
  492. if(usedin(t, &p->from))
  493. break;
  494. if(usedin(t, &p->to)) {
  495. if(p->as == o)
  496. if(p->to.type == t)
  497. if(p->from.type == D_CONST)
  498. if(p->from.offset == s)
  499. return r;
  500. break;
  501. }
  502. }
  503. return R;
  504. }
  505. int
  506. regtyp(int t)
  507. {
  508. if(t >= D_R0 && t < D_R0+8)
  509. return 1;
  510. if(t >= D_A0 && t < D_A0+8)
  511. return 1;
  512. if(t >= D_F0 && t < D_F0+8)
  513. return 1;
  514. return 0;
  515. }
  516. int
  517. anyvar(Adr *a)
  518. {
  519. if(regtyp(a->type))
  520. return 1;
  521. return 0;
  522. if(a->type == D_AUTO || a->type == D_PARAM)
  523. return 1;
  524. return 0;
  525. }
  526. /*
  527. * the idea is to substitute
  528. * one register for another
  529. * from one MOV to another
  530. * MOV a, R0
  531. * ADD b, R0 / no use of R1
  532. * MOV R0, R1
  533. * would be converted to
  534. * MOV a, R1
  535. * ADD b, R1
  536. * MOV R1, R0
  537. * hopefully, then the former or latter MOVL
  538. * will be eliminated by copy propagation.
  539. */
  540. int
  541. subprop(Reg *r0)
  542. {
  543. Prog *p;
  544. Adr *v1, *v2;
  545. Reg *r;
  546. int t;
  547. p = r0->prog;
  548. v1 = &p->from;
  549. if(!regtyp(v1->type))
  550. return 0;
  551. v2 = &p->to;
  552. if(!regtyp(v2->type))
  553. return 0;
  554. for(r=uniqp(r0); r!=R; r=uniqp(r)) {
  555. if(uniqs(r) == R)
  556. break;
  557. p = r->prog;
  558. switch(p->as) {
  559. case ADIVUW: /* these set Rn and Rn+1 */
  560. case ADIVUL:
  561. case ADIVSW:
  562. case ADIVSL:
  563. case ABSR:
  564. return 0;
  565. case AFMOVED:
  566. case AFMOVEF:
  567. case AMOVL:
  568. if(p->to.type == v1->type)
  569. goto gotit;
  570. }
  571. if(copyau(&p->from, v2) || copyau(&p->to, v2))
  572. break;
  573. if(copysub(&p->from, v1, v2, p, 0) || copysub(&p->to, v1, v2, p, 0))
  574. break;
  575. }
  576. return 0;
  577. gotit:
  578. copysub(&p->to, v1, v2, p, 1);
  579. if(debug['P']) {
  580. print("gotit: %D->%D\n%P", v1, v2, r->prog);
  581. if(p->from.type == v2->type)
  582. print(" excise");
  583. print("\n");
  584. }
  585. if(p->from.type == v2->type)
  586. excise(r);
  587. for(r=uniqs(r); r!=r0; r=uniqs(r)) {
  588. p = r->prog;
  589. copysub(&p->from, v1, v2, p, 1);
  590. copysub(&p->to, v1, v2, p, 1);
  591. if(debug['P'])
  592. print("%P\n", r->prog);
  593. }
  594. t = v1->type;
  595. v1->type = v2->type;
  596. v2->type = t;
  597. if(debug['P'])
  598. print("%P last\n", r->prog);
  599. return 1;
  600. }
  601. /*
  602. * The idea is to remove redundant copies.
  603. * v1->v2 F=0
  604. * (use v2 s/v2/v1/)*
  605. * set v1 F=1
  606. * use v2 return fail
  607. * -----------------
  608. * v1->v2 F=0
  609. * (use v2 s/v2/v1/)*
  610. * set v1 F=1
  611. * set v2 return success
  612. */
  613. int
  614. copyprop(Reg *r0)
  615. {
  616. Prog *p;
  617. Adr *v1, *v2;
  618. Reg *r;
  619. p = r0->prog;
  620. v1 = &p->from;
  621. v2 = &p->to;
  622. if(copyas(v1, v2))
  623. return 1;
  624. for(r=firstr; r!=R; r=r->link)
  625. r->active = 0;
  626. return copy1(v1, v2, r0->s1, 0);
  627. }
  628. int
  629. copy1(Adr *v1, Adr *v2, Reg *r, int f)
  630. {
  631. int t;
  632. if(r->active) {
  633. if(debug['P'])
  634. print("copyret 1\n");
  635. return 1;
  636. }
  637. r->active = 1;
  638. if(debug['P'])
  639. print("copy %D->%D\n", v1, v2);
  640. for(; r != R; r = r->s1) {
  641. if(debug['P'])
  642. print("%P", r->prog);
  643. if(!f && uniqp(r) == R) {
  644. f = 1;
  645. if(debug['P'])
  646. print("; merge; f=%d", f);
  647. }
  648. t = copyu(r->prog, v2, A);
  649. switch(t) {
  650. case 2: /* rar, cant split */
  651. if(debug['P'])
  652. print("; rar return 0\n");
  653. return 0;
  654. case 3: /* set */
  655. if(debug['P'])
  656. print("; set; return 1\n");
  657. return 1;
  658. case 1: /* used, substitute */
  659. case 4: /* use and set */
  660. if(f) {
  661. if(debug['P'])
  662. print("; used and f; return 0\n");
  663. return 0;
  664. }
  665. if(copyu(r->prog, v2, v1)) {
  666. if(debug['P'])
  667. print("; sub fail; return 0\n");
  668. return 0;
  669. }
  670. if(debug['P'])
  671. print("; substitute");
  672. if(t == 4) {
  673. if(debug['P'])
  674. print("; used and set; return 1\n");
  675. return 1;
  676. }
  677. break;
  678. }
  679. if(!f) {
  680. t = copyu(r->prog, v1, A);
  681. if(!f && (t == 2 || t == 3 || t == 4)) {
  682. if(debug['P'])
  683. print("; f set used");
  684. f = 1;
  685. }
  686. }
  687. if(debug['P'])
  688. print("\n");
  689. if(r->s2)
  690. if(!copy1(v1, v2, r->s2, f))
  691. return 0;
  692. }
  693. return 1;
  694. }
  695. /*
  696. * return
  697. * 1 if v only used (and substitute),
  698. * 2 if read-alter-rewrite
  699. * 3 if set
  700. * 4 if set and used
  701. * 0 otherwise (not touched)
  702. */
  703. int
  704. copyu(Prog *p, Adr *v, Adr *s)
  705. {
  706. int t;
  707. switch(p->as) {
  708. default:
  709. if(debug['P'])
  710. print("unknown op %A\n", p->as);
  711. return 2;
  712. case APEA: /* rhs addr */
  713. if(copyas(&p->to, v))
  714. return 2;
  715. goto caseread;
  716. case ALEA: /* lhs addr, rhs store */
  717. if(copyas(&p->from, v))
  718. return 2;
  719. case AMOVL: /* rhs store */
  720. case ACLRL:
  721. case AFMOVEF:
  722. case AFMOVED:
  723. case AFMOVEB:
  724. case AFMOVEW:
  725. case AFMOVEL:
  726. case ANOP:
  727. if(copyas(&p->to, v)) {
  728. if(s != A)
  729. return copysub(&p->from, v, s, p, 1);
  730. if(copyau(&p->from, v))
  731. return 4;
  732. return 3;
  733. }
  734. goto caseread;
  735. case AADDL: /* rhs rar */
  736. case AADDW:
  737. case AADDB:
  738. case ASUBL:
  739. case ASUBW:
  740. case ASUBB:
  741. case AANDL:
  742. case AANDW:
  743. case AANDB:
  744. case AORL:
  745. case AORW:
  746. case AORB:
  747. case AEORL:
  748. case AEORW:
  749. case AEORB:
  750. case AASRL:
  751. case AASRW:
  752. case AASRB:
  753. case AASLL:
  754. case AASLW:
  755. case AASLB:
  756. case ALSRL:
  757. case ALSRW:
  758. case ALSRB:
  759. case ANOTL:
  760. case ANOTW:
  761. case ANOTB:
  762. case ANEGL:
  763. case ANEGW:
  764. case ANEGB:
  765. case AEXTBL:
  766. case AEXTWL:
  767. case AEXTBW:
  768. case AMULSL:
  769. case AMULUL:
  770. case AMOVW: /* only sets part of register */
  771. case AMOVB:
  772. case ACLRW:
  773. case ACLRB:
  774. case AFADDD:
  775. case AFMULD:
  776. case AFDIVD:
  777. case AFSUBD:
  778. case AFNEGD:
  779. case AFADDF:
  780. case AFMULF:
  781. case AFDIVF:
  782. case AFSUBF:
  783. case AFNEGF:
  784. if(copyas(&p->to, v))
  785. return 2;
  786. goto caseread;
  787. case ADBF: /* lhs rar */
  788. if(copyas(&p->from, v))
  789. return 2;
  790. goto caseread;
  791. case ACMPL: /* read only */
  792. case ACMPW:
  793. case ACMPB:
  794. case AFCMPF:
  795. case AFCMPD:
  796. case ATSTL:
  797. case ATSTW:
  798. case ATSTB:
  799. case AFTSTF:
  800. case AFTSTD:
  801. caseread:
  802. if(s != A) {
  803. if(copysub(&p->from, v, s, p, 1))
  804. return 1;
  805. return copysub(&p->to, v, s, p, 1);
  806. }
  807. if(copyau(&p->from, v))
  808. return 1;
  809. if(copyau(&p->to, v))
  810. return 1;
  811. break;
  812. case ABRA: /* no reference */
  813. case ABGE:
  814. case ABNE:
  815. case ABLE:
  816. case ABEQ:
  817. case ABHI:
  818. case ABLS:
  819. case ABMI:
  820. case ABPL:
  821. case ABGT:
  822. case ABLT:
  823. case ABCC:
  824. case ABCS:
  825. case AFBEQ:
  826. case AFBNE:
  827. case AFBGT:
  828. case AFBGE:
  829. case AFBLE:
  830. case AFBLT:
  831. case AADJSP:
  832. case ACASEW:
  833. break;
  834. case ADIVUW: /* these set Rn and Rn+1 */
  835. case ADIVUL:
  836. case ADIVSW:
  837. case ADIVSL:
  838. t = v->type;
  839. if(t == p->to.type || t == p->to.type+1)
  840. return 2;
  841. goto caseread;
  842. case ARTS: /* funny */
  843. t = v->type;
  844. if(t == D_R0 || t == D_F0)
  845. return 2;
  846. if(t >= D_R0 && t < D_R0+NREG)
  847. if(t-D_R0 > exregoffset)
  848. return 2;
  849. if(t >= D_A0 && t < D_A0+NREG)
  850. if(t-D_A0 > exaregoffset)
  851. return 2;
  852. if(t >= D_F0 && t < D_F0+NREG)
  853. if(t-D_F0 > exfregoffset)
  854. return 2;
  855. return 3;
  856. case ABSR: /* funny */
  857. t = v->type;
  858. if(t >= D_R0 && t < D_R0+NREG)
  859. if(t-D_R0 > exregoffset)
  860. return 2;
  861. if(t >= D_A0 && t < D_A0+NREG)
  862. if(t-D_A0 > exaregoffset)
  863. return 2;
  864. if(t >= D_F0 && t < D_F0+NREG)
  865. if(t-D_F0 > exfregoffset)
  866. return 2;
  867. if(copyau(&p->to, v))
  868. return 2;
  869. return 3;
  870. }
  871. return 0;
  872. }
  873. /*
  874. * direct reference,
  875. * could be set/use depending on
  876. * semantics
  877. */
  878. int
  879. copyas(Adr *a, Adr *v)
  880. {
  881. if(a->type != v->type)
  882. return 0;
  883. if(regtyp(v->type))
  884. return 1;
  885. if(v->type == D_AUTO || v->type == D_PARAM) {
  886. if(v->offset == a->offset)
  887. return 1;
  888. return 0;
  889. }
  890. return 0;
  891. }
  892. /*
  893. * indirect
  894. */
  895. int
  896. tasas(Adr *a, Adr *v)
  897. {
  898. int t;
  899. t = a->type;
  900. if(t < I_INDIR+D_A0 && t >= I_INDIR+D_A0+8)
  901. return 0;
  902. if(v->type != t)
  903. return 0;
  904. if(a->displace != v->displace)
  905. return 0;
  906. return 1;
  907. }
  908. /*
  909. * either direct or indirect
  910. */
  911. int
  912. copyau(Adr *a, Adr *v)
  913. {
  914. int t;
  915. if(copyas(a, v))
  916. return 1;
  917. t = v->type;
  918. if(regtyp(t)) {
  919. if((a->type & D_MASK) == t)
  920. return 1;
  921. }
  922. return 0;
  923. }
  924. /*
  925. * substitute s for v in a
  926. * return failure to substitute
  927. */
  928. int
  929. copysub(Adr *a, Adr *v, Adr *s, Prog *p, int f)
  930. {
  931. int t;
  932. if(copyas(a, v)) {
  933. t = s->type;
  934. if(t >= D_F0 && t < D_F0+8) {
  935. if(f)
  936. a->type = t;
  937. return 0;
  938. }
  939. if(t >= D_R0 && t < D_R0+8) {
  940. if(f)
  941. a->type = t;
  942. return 0;
  943. }
  944. if(!(t >= D_A0 && t < D_A0+8))
  945. return 1;
  946. switch(p->as) {
  947. default:
  948. return 1;
  949. case AMOVL:
  950. case AMOVW:
  951. case ACMPL:
  952. case ACMPW:
  953. break;
  954. case AADDL:
  955. case AADDW:
  956. case ASUBL:
  957. case ASUBW:
  958. if(a == &p->from && !regtyp(p->to.type))
  959. return 1;
  960. break;
  961. }
  962. if(f)
  963. a->type = t;
  964. return 0;
  965. }
  966. t = v->type;
  967. if(regtyp(t)) {
  968. if((a->type & D_MASK) == t) {
  969. if((s->type ^ t) & ~(NREG-1))
  970. return 1;
  971. if(f)
  972. a->type = (a->type & ~D_MASK) | s->type;
  973. return 0;
  974. }
  975. return 0;
  976. }
  977. return 0;
  978. }