peep.c 15 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060
  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. if(a->type == D_AUTO || a->type == D_PARAM)
  524. return 1;
  525. return 0;
  526. }
  527. /*
  528. * the idea is to substitute
  529. * one register for another
  530. * from one MOV to another
  531. * MOV a, R0
  532. * ADD b, R0 / no use of R1
  533. * MOV R0, R1
  534. * would be converted to
  535. * MOV a, R1
  536. * ADD b, R1
  537. * MOV R1, R0
  538. * hopefully, then the former or latter MOVL
  539. * will be eliminated by copy propagation.
  540. */
  541. int
  542. subprop(Reg *r0)
  543. {
  544. Prog *p;
  545. Adr *v1, *v2;
  546. Reg *r;
  547. int t;
  548. p = r0->prog;
  549. v1 = &p->from;
  550. if(!regtyp(v1->type))
  551. return 0;
  552. v2 = &p->to;
  553. if(!regtyp(v2->type))
  554. return 0;
  555. for(r=uniqp(r0); r!=R; r=uniqp(r)) {
  556. if(uniqs(r) == R)
  557. break;
  558. p = r->prog;
  559. switch(p->as) {
  560. case ADIVUW: /* these set Rn and Rn+1 */
  561. case ADIVUL:
  562. case ADIVSW:
  563. case ADIVSL:
  564. case ABSR:
  565. return 0;
  566. case AFMOVED:
  567. case AFMOVEF:
  568. case AMOVL:
  569. if(p->to.type == v1->type)
  570. goto gotit;
  571. }
  572. if(copyau(&p->from, v2) || copyau(&p->to, v2))
  573. break;
  574. if(copysub(&p->from, v1, v2, p, 0) || copysub(&p->to, v1, v2, p, 0))
  575. break;
  576. }
  577. return 0;
  578. gotit:
  579. copysub(&p->to, v1, v2, p, 1);
  580. if(debug['P']) {
  581. print("gotit: %D->%D\n%P", v1, v2, r->prog);
  582. if(p->from.type == v2->type)
  583. print(" excise");
  584. print("\n");
  585. }
  586. if(p->from.type == v2->type)
  587. excise(r);
  588. for(r=uniqs(r); r!=r0; r=uniqs(r)) {
  589. p = r->prog;
  590. copysub(&p->from, v1, v2, p, 1);
  591. copysub(&p->to, v1, v2, p, 1);
  592. if(debug['P'])
  593. print("%P\n", r->prog);
  594. }
  595. t = v1->type;
  596. v1->type = v2->type;
  597. v2->type = t;
  598. if(debug['P'])
  599. print("%P last\n", r->prog);
  600. return 1;
  601. }
  602. /*
  603. * The idea is to remove redundant copies.
  604. * v1->v2 F=0
  605. * (use v2 s/v2/v1/)*
  606. * set v1 F=1
  607. * use v2 return fail
  608. * -----------------
  609. * v1->v2 F=0
  610. * (use v2 s/v2/v1/)*
  611. * set v1 F=1
  612. * set v2 return success
  613. */
  614. int
  615. copyprop(Reg *r0)
  616. {
  617. Prog *p;
  618. Adr *v1, *v2;
  619. Reg *r;
  620. p = r0->prog;
  621. v1 = &p->from;
  622. v2 = &p->to;
  623. if(copyas(v1, v2))
  624. return 1;
  625. for(r=firstr; r!=R; r=r->link)
  626. r->active = 0;
  627. return copy1(v1, v2, r0->s1, 0);
  628. }
  629. int
  630. copy1(Adr *v1, Adr *v2, Reg *r, int f)
  631. {
  632. int t;
  633. if(r->active) {
  634. if(debug['P'])
  635. print("copyret 1\n");
  636. return 1;
  637. }
  638. r->active = 1;
  639. if(debug['P'])
  640. print("copy %D->%D\n", v1, v2);
  641. for(; r != R; r = r->s1) {
  642. if(debug['P'])
  643. print("%P", r->prog);
  644. if(!f && uniqp(r) == R) {
  645. f = 1;
  646. if(debug['P'])
  647. print("; merge; f=%d", f);
  648. }
  649. t = copyu(r->prog, v2, A);
  650. switch(t) {
  651. case 2: /* rar, cant split */
  652. if(debug['P'])
  653. print("; rar return 0\n");
  654. return 0;
  655. case 3: /* set */
  656. if(debug['P'])
  657. print("; set; return 1\n");
  658. return 1;
  659. case 1: /* used, substitute */
  660. case 4: /* use and set */
  661. if(f) {
  662. if(debug['P'])
  663. print("; used and f; return 0\n");
  664. return 0;
  665. }
  666. if(copyu(r->prog, v2, v1)) {
  667. if(debug['P'])
  668. print("; sub fail; return 0\n");
  669. return 0;
  670. }
  671. if(debug['P'])
  672. print("; substitute");
  673. if(t == 4) {
  674. if(debug['P'])
  675. print("; used and set; return 1\n");
  676. return 1;
  677. }
  678. break;
  679. }
  680. if(!f) {
  681. t = copyu(r->prog, v1, A);
  682. if(!f && (t == 2 || t == 3 || t == 4)) {
  683. if(debug['P'])
  684. print("; f set used");
  685. f = 1;
  686. }
  687. }
  688. if(debug['P'])
  689. print("\n");
  690. if(r->s2)
  691. if(!copy1(v1, v2, r->s2, f))
  692. return 0;
  693. }
  694. return 1;
  695. }
  696. /*
  697. * return
  698. * 1 if v only used (and substitute),
  699. * 2 if read-alter-rewrite
  700. * 3 if set
  701. * 4 if set and used
  702. * 0 otherwise (not touched)
  703. */
  704. int
  705. copyu(Prog *p, Adr *v, Adr *s)
  706. {
  707. int t;
  708. switch(p->as) {
  709. default:
  710. if(debug['P'])
  711. print("unknown op %A\n", p->as);
  712. return 2;
  713. case APEA: /* rhs addr */
  714. if(copyas(&p->to, v))
  715. return 2;
  716. goto caseread;
  717. case ALEA: /* lhs addr, rhs store */
  718. if(copyas(&p->from, v))
  719. return 2;
  720. case AMOVL: /* rhs store */
  721. case ACLRL:
  722. case AFMOVEF:
  723. case AFMOVED:
  724. case AFMOVEB:
  725. case AFMOVEW:
  726. case AFMOVEL:
  727. case ANOP:
  728. if(copyas(&p->to, v)) {
  729. if(s != A)
  730. return copysub(&p->from, v, s, p, 1);
  731. if(copyau(&p->from, v))
  732. return 4;
  733. return 3;
  734. }
  735. goto caseread;
  736. case AADDL: /* rhs rar */
  737. case AADDW:
  738. case AADDB:
  739. case ASUBL:
  740. case ASUBW:
  741. case ASUBB:
  742. case AANDL:
  743. case AANDW:
  744. case AANDB:
  745. case AORL:
  746. case AORW:
  747. case AORB:
  748. case AEORL:
  749. case AEORW:
  750. case AEORB:
  751. case AASRL:
  752. case AASRW:
  753. case AASRB:
  754. case AASLL:
  755. case AASLW:
  756. case AASLB:
  757. case ALSRL:
  758. case ALSRW:
  759. case ALSRB:
  760. case ANOTL:
  761. case ANOTW:
  762. case ANOTB:
  763. case ANEGL:
  764. case ANEGW:
  765. case ANEGB:
  766. case AEXTBL:
  767. case AEXTWL:
  768. case AEXTBW:
  769. case AMULSL:
  770. case AMULUL:
  771. case AMOVW: /* only sets part of register */
  772. case AMOVB:
  773. case ACLRW:
  774. case ACLRB:
  775. case AFADDD:
  776. case AFMULD:
  777. case AFDIVD:
  778. case AFSUBD:
  779. case AFNEGD:
  780. case AFADDF:
  781. case AFMULF:
  782. case AFDIVF:
  783. case AFSUBF:
  784. case AFNEGF:
  785. if(copyas(&p->to, v))
  786. return 2;
  787. goto caseread;
  788. case ADBF: /* lhs rar */
  789. if(copyas(&p->from, v))
  790. return 2;
  791. goto caseread;
  792. case ACMPL: /* read only */
  793. case ACMPW:
  794. case ACMPB:
  795. case AFCMPF:
  796. case AFCMPD:
  797. case ATSTL:
  798. case ATSTW:
  799. case ATSTB:
  800. case AFTSTF:
  801. case AFTSTD:
  802. caseread:
  803. if(s != A) {
  804. if(copysub(&p->from, v, s, p, 1))
  805. return 1;
  806. return copysub(&p->to, v, s, p, 1);
  807. }
  808. if(copyau(&p->from, v))
  809. return 1;
  810. if(copyau(&p->to, v))
  811. return 1;
  812. break;
  813. case ABRA: /* no reference */
  814. case ABGE:
  815. case ABNE:
  816. case ABLE:
  817. case ABEQ:
  818. case ABHI:
  819. case ABLS:
  820. case ABMI:
  821. case ABPL:
  822. case ABGT:
  823. case ABLT:
  824. case ABCC:
  825. case ABCS:
  826. case AFBEQ:
  827. case AFBNE:
  828. case AFBGT:
  829. case AFBGE:
  830. case AFBLE:
  831. case AFBLT:
  832. case AADJSP:
  833. case ACASEW:
  834. break;
  835. case ADIVUW: /* these set Rn and Rn+1 */
  836. case ADIVUL:
  837. case ADIVSW:
  838. case ADIVSL:
  839. t = v->type;
  840. if(t == p->to.type || t == p->to.type+1)
  841. return 2;
  842. goto caseread;
  843. case ARTS: /* funny */
  844. t = v->type;
  845. if(t == D_R0 || t == D_F0)
  846. return 2;
  847. if(t >= D_R0 && t < D_R0+NREG)
  848. if(t-D_R0 > exregoffset)
  849. return 2;
  850. if(t >= D_A0 && t < D_A0+NREG)
  851. if(t-D_A0 > exaregoffset)
  852. return 2;
  853. if(t >= D_F0 && t < D_F0+NREG)
  854. if(t-D_F0 > exfregoffset)
  855. return 2;
  856. return 3;
  857. case ABSR: /* funny */
  858. t = v->type;
  859. if(t >= D_R0 && t < D_R0+NREG)
  860. if(t-D_R0 > exregoffset)
  861. return 2;
  862. if(t >= D_A0 && t < D_A0+NREG)
  863. if(t-D_A0 > exaregoffset)
  864. return 2;
  865. if(t >= D_F0 && t < D_F0+NREG)
  866. if(t-D_F0 > exfregoffset)
  867. return 2;
  868. if(copyau(&p->to, v))
  869. return 2;
  870. return 3;
  871. }
  872. return 0;
  873. }
  874. /*
  875. * direct reference,
  876. * could be set/use depending on
  877. * semantics
  878. */
  879. int
  880. copyas(Adr *a, Adr *v)
  881. {
  882. if(a->type != v->type)
  883. return 0;
  884. if(regtyp(v->type))
  885. return 1;
  886. if(v->type == D_AUTO || v->type == D_PARAM) {
  887. if(v->offset == a->offset)
  888. return 1;
  889. return 0;
  890. }
  891. return 0;
  892. }
  893. /*
  894. * indirect
  895. */
  896. int
  897. tasas(Adr *a, Adr *v)
  898. {
  899. int t;
  900. t = a->type;
  901. if(t < I_INDIR+D_A0 && t >= I_INDIR+D_A0+8)
  902. return 0;
  903. if(v->type != t)
  904. return 0;
  905. if(a->displace != v->displace)
  906. return 0;
  907. return 1;
  908. }
  909. /*
  910. * either direct or indirect
  911. */
  912. int
  913. copyau(Adr *a, Adr *v)
  914. {
  915. int t;
  916. if(copyas(a, v))
  917. return 1;
  918. t = v->type;
  919. if(regtyp(t)) {
  920. if((a->type & D_MASK) == t)
  921. return 1;
  922. }
  923. return 0;
  924. }
  925. /*
  926. * substitute s for v in a
  927. * return failure to substitute
  928. */
  929. int
  930. copysub(Adr *a, Adr *v, Adr *s, Prog *p, int f)
  931. {
  932. int t;
  933. if(copyas(a, v)) {
  934. t = s->type;
  935. if(t >= D_F0 && t < D_F0+8) {
  936. if(f)
  937. a->type = t;
  938. return 0;
  939. }
  940. if(t >= D_R0 && t < D_R0+8) {
  941. if(f)
  942. a->type = t;
  943. return 0;
  944. }
  945. if(!(t >= D_A0 && t < D_A0+8))
  946. return 1;
  947. switch(p->as) {
  948. default:
  949. return 1;
  950. case AMOVL:
  951. case AMOVW:
  952. case ACMPL:
  953. case ACMPW:
  954. break;
  955. case AADDL:
  956. case AADDW:
  957. case ASUBL:
  958. case ASUBW:
  959. if(a == &p->from && !regtyp(p->to.type))
  960. return 1;
  961. break;
  962. }
  963. if(f)
  964. a->type = t;
  965. return 0;
  966. }
  967. t = v->type;
  968. if(regtyp(t)) {
  969. if((a->type & D_MASK) == t) {
  970. if((s->type ^ t) & ~(NREG-1))
  971. return 1;
  972. if(f)
  973. a->type = (a->type & ~D_MASK) | s->type;
  974. return 0;
  975. }
  976. return 0;
  977. }
  978. return 0;
  979. }