peep.c 15 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073
  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. if(a->index != D_NONE)
  323. return 0;
  324. if(b->index != D_NONE)
  325. return 0;
  326. o = a->type;
  327. if((o >= D_R0 && o < D_R0+NREG) ||
  328. (o >= D_A0 && o < D_A0+NREG))
  329. return o == b->type;
  330. o &= D_MASK;
  331. if(o >= D_A0 && o < D_A0+NREG) {
  332. if(o != (b->type&D_MASK))
  333. return 0;
  334. if(a->offset != b->offset)
  335. return 0;
  336. o = a->type & I_MASK;
  337. if(o == I_INDIR) {
  338. o = b->type & I_MASK;
  339. if(o == I_INDIR || o == I_INDDEC)
  340. return 1;
  341. return 0;
  342. }
  343. if(o == I_INDINC) {
  344. o = b->type & I_MASK;
  345. if(o == I_INDIR) {
  346. b->type += I_INDINC-I_INDIR;
  347. return 1;
  348. }
  349. if(o == I_INDDEC) {
  350. b->type += I_INDIR-I_INDDEC;
  351. return 1;
  352. }
  353. return 0;
  354. }
  355. }
  356. return 0;
  357. }
  358. int
  359. aregind(Adr *a)
  360. {
  361. int t;
  362. t = a->type;
  363. if(t >= (D_A0|I_INDIR) && t < ((D_A0+NREG)|I_INDIR))
  364. while(a->offset == 0 && a->index == D_NONE)
  365. return t & D_MASK;
  366. return D_NONE;
  367. }
  368. int
  369. asize(int a)
  370. {
  371. switch(a) {
  372. case AFTSTD:
  373. case AFMOVED:
  374. case AFADDD:
  375. case AFSUBD:
  376. case AFMULD:
  377. case AFDIVD:
  378. case AFCMPD:
  379. case AFNEGD:
  380. return 8;
  381. case AFTSTF:
  382. case AFMOVEF:
  383. case AFADDF:
  384. case AFSUBF:
  385. case AFMULF:
  386. case AFDIVF:
  387. case AFCMPF:
  388. case AFNEGF:
  389. case ACLRL:
  390. case ATSTL:
  391. case AMOVL:
  392. case AADDL:
  393. case ASUBL:
  394. case ACMPL:
  395. case AANDL:
  396. case AORL:
  397. case AEORL:
  398. case ALSLL:
  399. case ALSRL:
  400. case AASLL:
  401. case AASRL:
  402. case ANEGL:
  403. return 4;
  404. case ACLRW:
  405. case ATSTW:
  406. case AMOVW:
  407. case AADDW:
  408. case ASUBW:
  409. case ACMPW:
  410. case AANDW:
  411. case AORW:
  412. case AEORW:
  413. case ALSLW:
  414. case ALSRW:
  415. case AASLW:
  416. case AASRW:
  417. case ANEGW:
  418. return 2;
  419. case ACLRB:
  420. case ATSTB:
  421. case AMOVB:
  422. case AADDB:
  423. case ASUBB:
  424. case ACMPB:
  425. case AANDB:
  426. case AORB:
  427. case AEORB:
  428. case ALSLB:
  429. case ALSRB:
  430. case AASLB:
  431. case AASRB:
  432. case ANEGB:
  433. return 1;
  434. }
  435. if(debug['P'])
  436. print("unknown asize %A\n", p->as);
  437. return 0;
  438. }
  439. int
  440. usedin(int t, Adr *a)
  441. {
  442. if((a->type&D_MASK) == t)
  443. return 1;
  444. if((a->index&D_MASK) == t)
  445. return 1;
  446. return 0;
  447. }
  448. Reg*
  449. findccr(Reg *r)
  450. {
  451. Prog *p;
  452. for(;;) {
  453. r = uniqs(r);
  454. if(r == R)
  455. break;
  456. p = r->prog;
  457. if(p->to.type == D_CCR)
  458. return r;
  459. if(setccr(p))
  460. break;
  461. }
  462. return R;
  463. }
  464. int
  465. setccr(Prog *p)
  466. {
  467. switch(p->as) {
  468. case ANOP:
  469. return 0;
  470. case AADDL:
  471. case AMOVL:
  472. case ACLRL:
  473. if(p->to.type >= D_A0 && p->to.type < D_A0+8)
  474. return 0;
  475. }
  476. return 1;
  477. }
  478. Reg*
  479. findop(Reg *r, int t, int o, int s)
  480. {
  481. Prog *p;
  482. Reg *r1;
  483. for(;;) {
  484. if(o == AADDL) {
  485. r1 = uniqs(r);
  486. if(r1 == R)
  487. break;
  488. if(uniqp(r1) != r)
  489. break;
  490. } else {
  491. r1 = uniqp(r);
  492. if(r1 == R)
  493. break;
  494. if(uniqs(r1) != r)
  495. break;
  496. }
  497. r = r1;
  498. p = r->prog;
  499. if(usedin(t, &p->from))
  500. break;
  501. if(usedin(t, &p->to)) {
  502. if(p->as == o)
  503. if(p->to.type == t)
  504. if(p->to.index == D_NONE)
  505. if(p->from.type == D_CONST)
  506. if(p->from.offset == s)
  507. return r;
  508. break;
  509. }
  510. }
  511. return R;
  512. }
  513. int
  514. regtyp(int t)
  515. {
  516. if(t >= D_R0 && t < D_R0+8)
  517. return 1;
  518. if(t >= D_A0 && t < D_A0+8)
  519. return 1;
  520. if(t >= D_F0 && t < D_F0+8)
  521. return 1;
  522. return 0;
  523. }
  524. int
  525. anyvar(Adr *a)
  526. {
  527. if(regtyp(a->type))
  528. return 1;
  529. return 0;
  530. }
  531. /*
  532. * the idea is to substitute
  533. * one register for another
  534. * from one MOV to another
  535. * MOV a, R0
  536. * ADD b, R0 / no use of R1
  537. * MOV R0, R1
  538. * would be converted to
  539. * MOV a, R1
  540. * ADD b, R1
  541. * MOV R1, R0
  542. * hopefully, then the former or latter MOVL
  543. * will be eliminated by copy propagation.
  544. */
  545. int
  546. subprop(Reg *r0)
  547. {
  548. Prog *p;
  549. Adr *v1, *v2;
  550. Reg *r;
  551. int t;
  552. p = r0->prog;
  553. v1 = &p->from;
  554. if(!regtyp(v1->type))
  555. return 0;
  556. v2 = &p->to;
  557. if(!regtyp(v2->type))
  558. return 0;
  559. for(r=uniqp(r0); r!=R; r=uniqp(r)) {
  560. if(uniqs(r) == R)
  561. break;
  562. p = r->prog;
  563. switch(p->as) {
  564. case ADIVUW: /* these set Rn and Rn+1 */
  565. case ADIVUL:
  566. case ADIVSW:
  567. case ADIVSL:
  568. case ABSR:
  569. return 0;
  570. case AFMOVED:
  571. case AFMOVEF:
  572. case AMOVL:
  573. if(p->to.type == v1->type)
  574. goto gotit;
  575. }
  576. if(copyau(&p->from, v2) || copyau(&p->to, v2))
  577. break;
  578. if(copysub(&p->from, v1, v2, p, 0) || copysub(&p->to, v1, v2, p, 0))
  579. break;
  580. }
  581. return 0;
  582. gotit:
  583. copysub(&p->to, v1, v2, p, 1);
  584. if(debug['P']) {
  585. print("gotit: %D->%D\n%P", v1, v2, r->prog);
  586. if(p->from.type == v2->type)
  587. print(" excise");
  588. print("\n");
  589. }
  590. if(p->from.type == v2->type)
  591. excise(r);
  592. for(r=uniqs(r); r!=r0; r=uniqs(r)) {
  593. p = r->prog;
  594. copysub(&p->from, v1, v2, p, 1);
  595. copysub(&p->to, v1, v2, p, 1);
  596. if(debug['P'])
  597. print("%P\n", r->prog);
  598. }
  599. t = v1->type;
  600. v1->type = v2->type;
  601. v2->type = t;
  602. if(debug['P'])
  603. print("%P last\n", r->prog);
  604. return 1;
  605. }
  606. /*
  607. * The idea is to remove redundant copies.
  608. * v1->v2 F=0
  609. * (use v2 s/v2/v1/)*
  610. * set v1 F=1
  611. * use v2 return fail
  612. * -----------------
  613. * v1->v2 F=0
  614. * (use v2 s/v2/v1/)*
  615. * set v1 F=1
  616. * set v2 return success
  617. */
  618. int
  619. copyprop(Reg *r0)
  620. {
  621. Prog *p;
  622. Adr *v1, *v2;
  623. Reg *r;
  624. p = r0->prog;
  625. v1 = &p->from;
  626. v2 = &p->to;
  627. if(copyas(v1, v2))
  628. return 1;
  629. for(r=firstr; r!=R; r=r->link)
  630. r->active = 0;
  631. return copy1(v1, v2, r0->s1, 0);
  632. }
  633. int
  634. copy1(Adr *v1, Adr *v2, Reg *r, int f)
  635. {
  636. int t;
  637. if(r->active) {
  638. if(debug['P'])
  639. print("copyret 1\n");
  640. return 1;
  641. }
  642. r->active = 1;
  643. if(debug['P'])
  644. print("copy %D->%D\n", v1, v2);
  645. for(; r != R; r = r->s1) {
  646. if(debug['P'])
  647. print("%P", r->prog);
  648. if(!f && uniqp(r) == R) {
  649. f = 1;
  650. if(debug['P'])
  651. print("; merge; f=%d", f);
  652. }
  653. t = copyu(r->prog, v2, A);
  654. switch(t) {
  655. case 2: /* rar, cant split */
  656. if(debug['P'])
  657. print("; rar return 0\n");
  658. return 0;
  659. case 3: /* set */
  660. if(debug['P'])
  661. print("; set; return 1\n");
  662. return 1;
  663. case 1: /* used, substitute */
  664. case 4: /* use and set */
  665. if(f) {
  666. if(debug['P'])
  667. print("; used and f; return 0\n");
  668. return 0;
  669. }
  670. if(copyu(r->prog, v2, v1)) {
  671. if(debug['P'])
  672. print("; sub fail; return 0\n");
  673. return 0;
  674. }
  675. if(debug['P'])
  676. print("; substitute");
  677. if(t == 4) {
  678. if(debug['P'])
  679. print("; used and set; return 1\n");
  680. return 1;
  681. }
  682. break;
  683. }
  684. if(!f) {
  685. t = copyu(r->prog, v1, A);
  686. if(!f && (t == 2 || t == 3 || t == 4)) {
  687. if(debug['P'])
  688. print("; f set used");
  689. f = 1;
  690. }
  691. }
  692. if(debug['P'])
  693. print("\n");
  694. if(r->s2)
  695. if(!copy1(v1, v2, r->s2, f))
  696. return 0;
  697. }
  698. return 1;
  699. }
  700. /*
  701. * return
  702. * 1 if v only used (and substitute),
  703. * 2 if read-alter-rewrite
  704. * 3 if set
  705. * 4 if set and used
  706. * 0 otherwise (not touched)
  707. */
  708. int
  709. copyu(Prog *p, Adr *v, Adr *s)
  710. {
  711. int t;
  712. switch(p->as) {
  713. default:
  714. if(debug['P'])
  715. print("unknown op %A\n", p->as);
  716. return 2;
  717. case APEA: /* rhs addr */
  718. if(copyas(&p->to, v))
  719. return 2;
  720. goto caseread;
  721. case ALEA: /* lhs addr, rhs store */
  722. if(copyas(&p->from, v))
  723. return 2;
  724. case AMOVL: /* rhs store */
  725. case ACLRL:
  726. case AFMOVEF:
  727. case AFMOVED:
  728. case AFMOVEB:
  729. case AFMOVEW:
  730. case AFMOVEL:
  731. case ANOP:
  732. if(copyas(&p->to, v)) {
  733. if(s != A)
  734. return copysub(&p->from, v, s, p, 1);
  735. if(copyau(&p->from, v))
  736. return 4;
  737. return 3;
  738. }
  739. goto caseread;
  740. case AADDL: /* rhs rar */
  741. case AADDW:
  742. case AADDB:
  743. case ASUBL:
  744. case ASUBW:
  745. case ASUBB:
  746. case AANDL:
  747. case AANDW:
  748. case AANDB:
  749. case AORL:
  750. case AORW:
  751. case AORB:
  752. case AEORL:
  753. case AEORW:
  754. case AEORB:
  755. case AASRL:
  756. case AASRW:
  757. case AASRB:
  758. case AASLL:
  759. case AASLW:
  760. case AASLB:
  761. case ALSRL:
  762. case ALSRW:
  763. case ALSRB:
  764. case ANOTL:
  765. case ANOTW:
  766. case ANOTB:
  767. case ANEGL:
  768. case ANEGW:
  769. case ANEGB:
  770. case AEXTBL:
  771. case AEXTWL:
  772. case AEXTBW:
  773. case AMULSL:
  774. case AMULUL:
  775. case AMOVW: /* only sets part of register */
  776. case AMOVB:
  777. case ACLRW:
  778. case ACLRB:
  779. case AFADDD:
  780. case AFMULD:
  781. case AFDIVD:
  782. case AFSUBD:
  783. case AFNEGD:
  784. case AFADDF:
  785. case AFMULF:
  786. case AFDIVF:
  787. case AFSUBF:
  788. case AFNEGF:
  789. if(copyas(&p->to, v))
  790. return 2;
  791. goto caseread;
  792. case ADBF: /* lhs rar */
  793. if(copyas(&p->from, v))
  794. return 2;
  795. goto caseread;
  796. case ACMPL: /* read only */
  797. case ACMPW:
  798. case ACMPB:
  799. case AFCMPF:
  800. case AFCMPD:
  801. case ATSTL:
  802. case ATSTW:
  803. case ATSTB:
  804. case AFTSTF:
  805. case AFTSTD:
  806. caseread:
  807. if(s != A) {
  808. if(copysub(&p->from, v, s, p, 1))
  809. return 1;
  810. return copysub(&p->to, v, s, p, 1);
  811. }
  812. if(copyau(&p->from, v))
  813. return 1;
  814. if(copyau(&p->to, v))
  815. return 1;
  816. break;
  817. case ABRA: /* no reference */
  818. case ABGE:
  819. case ABNE:
  820. case ABLE:
  821. case ABEQ:
  822. case ABHI:
  823. case ABLS:
  824. case ABMI:
  825. case ABPL:
  826. case ABGT:
  827. case ABLT:
  828. case ABCC:
  829. case ABCS:
  830. case AFBEQ:
  831. case AFBNE:
  832. case AFBGT:
  833. case AFBGE:
  834. case AFBLE:
  835. case AFBLT:
  836. case AADJSP:
  837. case ACASEW:
  838. break;
  839. case ADIVUW: /* these set Rn and Rn+1 */
  840. case ADIVUL:
  841. case ADIVSW:
  842. case ADIVSL:
  843. t = v->type;
  844. if(t == p->to.type || t == p->to.type+1)
  845. return 2;
  846. goto caseread;
  847. case ARTS: /* funny */
  848. t = v->type;
  849. if(t == D_R0 || t == D_F0)
  850. return 2;
  851. if(t >= D_R0 && t < D_R0+NREG)
  852. if(t-D_R0 > exregoffset)
  853. return 2;
  854. if(t >= D_A0 && t < D_A0+NREG)
  855. if(t-D_A0 > exaregoffset)
  856. return 2;
  857. if(t >= D_F0 && t < D_F0+NREG)
  858. if(t-D_F0 > exfregoffset)
  859. return 2;
  860. return 3;
  861. case ABSR: /* funny */
  862. t = v->type;
  863. if(t >= D_R0 && t < D_R0+NREG)
  864. if(t-D_R0 > exregoffset)
  865. return 2;
  866. if(t >= D_A0 && t < D_A0+NREG)
  867. if(t-D_A0 > exaregoffset)
  868. return 2;
  869. if(t >= D_F0 && t < D_F0+NREG)
  870. if(t-D_F0 > exfregoffset)
  871. return 2;
  872. return 3;
  873. }
  874. return 0;
  875. }
  876. /*
  877. * direct reference,
  878. * could be set/use depending on
  879. * semantics
  880. */
  881. int
  882. copyas(Adr *a, Adr *v)
  883. {
  884. if(a->type != v->type)
  885. return 0;
  886. if(regtyp(v->type))
  887. return 1;
  888. if(v->type == D_AUTO || v->type == D_PARAM) {
  889. if(v->offset == a->offset)
  890. return 1;
  891. return 0;
  892. }
  893. return 0;
  894. }
  895. /*
  896. * indirect
  897. */
  898. int
  899. tasas(Adr *a, Adr *v)
  900. {
  901. int t;
  902. if(a->index != D_NONE)
  903. return 0;
  904. if(v->index != D_NONE)
  905. return 0;
  906. t = a->type;
  907. if(t < I_INDIR+D_A0 && t >= I_INDIR+D_A0+8)
  908. return 0;
  909. if(v->type != t)
  910. return 0;
  911. if(a->displace != v->displace)
  912. return 0;
  913. return 1;
  914. }
  915. /*
  916. * either direct or indirect
  917. */
  918. int
  919. copyau(Adr *a, Adr *v)
  920. {
  921. int t;
  922. if(copyas(a, v))
  923. return 1;
  924. t = v->type;
  925. if(regtyp(t)) {
  926. if((a->type & D_MASK) == t)
  927. return 1;
  928. if((a->index & D_MASK) == t)
  929. return 1;
  930. }
  931. return 0;
  932. }
  933. /*
  934. * substitute s for v in a
  935. * return failure to substitute
  936. */
  937. int
  938. copysub(Adr *a, Adr *v, Adr *s, Prog *p, int f)
  939. {
  940. int t;
  941. if(copyas(a, v)) {
  942. t = s->type;
  943. if(t >= D_F0 && t < D_F0+8) {
  944. if(f)
  945. a->type = t;
  946. return 0;
  947. }
  948. if(t >= D_R0 && t < D_R0+8) {
  949. if(f)
  950. a->type = t;
  951. return 0;
  952. }
  953. if(!(t >= D_A0 && t < D_A0+8))
  954. return 1;
  955. switch(p->as) {
  956. default:
  957. return 1;
  958. case AMOVL:
  959. case AMOVW:
  960. case ACMPL:
  961. case ACMPW:
  962. break;
  963. case AADDL:
  964. case AADDW:
  965. case ASUBL:
  966. case ASUBW:
  967. if(a == &p->from && !regtyp(p->to.type))
  968. return 1;
  969. break;
  970. }
  971. if(f)
  972. a->type = t;
  973. return 0;
  974. }
  975. t = v->type;
  976. if(regtyp(t)) {
  977. if((a->type & D_MASK) == t) {
  978. if((s->type ^ t) & ~(NREG-1))
  979. return 1;
  980. if(f)
  981. a->type = (a->type & ~D_MASK) | s->type;
  982. return 0;
  983. }
  984. if((a->index & D_MASK) == t) {
  985. if(f)
  986. a->index = (a->index & ~D_MASK) | s->type;
  987. return 0;
  988. }
  989. return 0;
  990. }
  991. return 0;
  992. }