peep.c 15 KB

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