peep.c 16 KB

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