peep.c 17 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042
  1. #include "gc.h"
  2. static Reg*
  3. rnops(Reg *r)
  4. {
  5. Prog *p;
  6. Reg *r1;
  7. if(r != R)
  8. for(;;){
  9. p = r->prog;
  10. if(p->as != ANOP || p->from.type != D_NONE || p->to.type != D_NONE)
  11. break;
  12. r1 = uniqs(r);
  13. if(r1 == R)
  14. break;
  15. r = r1;
  16. }
  17. return r;
  18. }
  19. void
  20. peep(void)
  21. {
  22. Reg *r, *r1, *r2;
  23. Prog *p, *p1;
  24. int t;
  25. /*
  26. * complete R structure
  27. */
  28. t = 0;
  29. for(r=firstr; r!=R; r=r1) {
  30. r1 = r->link;
  31. if(r1 == R)
  32. break;
  33. p = r->prog->link;
  34. while(p != r1->prog)
  35. switch(p->as) {
  36. default:
  37. r2 = rega();
  38. r->link = r2;
  39. r2->link = r1;
  40. r2->prog = p;
  41. r2->p1 = r;
  42. r->s1 = r2;
  43. r2->s1 = r1;
  44. r1->p1 = r2;
  45. r = r2;
  46. t++;
  47. case ADATA:
  48. case AGLOBL:
  49. case ANAME:
  50. case ASIGNAME:
  51. p = p->link;
  52. }
  53. }
  54. loop1:
  55. t = 0;
  56. for(r=firstr; r!=R; r=r->link) {
  57. p = r->prog;
  58. if(p->as == AMOVW || p->as == AMOVD || p->as == AFMOVS || p->as == AFMOVD)
  59. if(regtyp(&p->to)) {
  60. if(regtyp(&p->from))
  61. if(p->from.type == p->to.type) {
  62. if(copyprop(r)) {
  63. excise(r);
  64. t++;
  65. } else
  66. if(subprop(r) && copyprop(r)) {
  67. excise(r);
  68. t++;
  69. }
  70. }
  71. if(regzer(&p->from))
  72. if(p->to.type == D_REG) {
  73. p->from.type = D_REG;
  74. p->from.reg = REGZERO;
  75. if(copyprop(r)) {
  76. excise(r);
  77. t++;
  78. } else
  79. if(subprop(r) && copyprop(r)) {
  80. excise(r);
  81. t++;
  82. }
  83. }
  84. }
  85. }
  86. if(t)
  87. goto loop1;
  88. /*
  89. * look for MOVB x,R; MOVB R,R
  90. */
  91. for(r=firstr; r!=R; r=r->link) {
  92. p = r->prog;
  93. switch(p->as) {
  94. default:
  95. continue;
  96. case AMOVH:
  97. case AMOVHZ:
  98. case AMOVB:
  99. case AMOVBZ:
  100. case AMOVW:
  101. case AMOVWZ:
  102. if(p->to.type != D_REG)
  103. continue;
  104. break;
  105. }
  106. r1 = r->link;
  107. if(r1 == R)
  108. continue;
  109. p1 = r1->prog;
  110. if(p1->as != p->as)
  111. continue;
  112. if(p1->from.type != D_REG || p1->from.reg != p->to.reg)
  113. continue;
  114. if(p1->to.type != D_REG || p1->to.reg != p->to.reg)
  115. continue;
  116. excise(r1);
  117. }
  118. if(debug['D'] > 1)
  119. return; /* allow following code improvement to be suppressed */
  120. /*
  121. * look for OP x,y,R; CMP R, $0 -> OPCC x,y,R
  122. * when OP can set condition codes correctly
  123. */
  124. for(r=firstr; r!=R; r=r->link) {
  125. p = r->prog;
  126. switch(p->as) {
  127. case ACMP:
  128. case ACMPW: /* always safe? */
  129. if(!regzer(&p->to))
  130. continue;
  131. r1 = r->s1;
  132. if(r1 == R)
  133. continue;
  134. switch(r1->prog->as) {
  135. default:
  136. continue;
  137. case ABCL:
  138. case ABC:
  139. /* the conditions can be complex and these are currently little used */
  140. continue;
  141. case ABEQ:
  142. case ABGE:
  143. case ABGT:
  144. case ABLE:
  145. case ABLT:
  146. case ABNE:
  147. case ABVC:
  148. case ABVS:
  149. break;
  150. }
  151. r1 = r;
  152. do
  153. r1 = uniqp(r1);
  154. while (r1 != R && r1->prog->as == ANOP);
  155. if(r1 == R)
  156. continue;
  157. p1 = r1->prog;
  158. if(p1->to.type != D_REG || p1->to.reg != p->from.reg)
  159. continue;
  160. switch(p1->as) {
  161. case ASUB:
  162. case AADD:
  163. case AXOR:
  164. case AOR:
  165. /* irregular instructions */
  166. if(p1->from.type == D_CONST)
  167. continue;
  168. break;
  169. }
  170. switch(p1->as) {
  171. default:
  172. continue;
  173. case AMOVW:
  174. case AMOVD:
  175. if(p1->from.type != D_REG)
  176. continue;
  177. continue;
  178. case AANDCC:
  179. case AANDNCC:
  180. case AORCC:
  181. case AORNCC:
  182. case AXORCC:
  183. case ASUBCC:
  184. case ASUBECC:
  185. case ASUBMECC:
  186. case ASUBZECC:
  187. case AADDCC:
  188. case AADDCCC:
  189. case AADDECC:
  190. case AADDMECC:
  191. case AADDZECC:
  192. case ARLWMICC:
  193. case ARLWNMCC:
  194. t = p1->as;
  195. break;
  196. /* don't deal with floating point instructions for now */
  197. /*
  198. case AFABS: t = AFABSCC; break;
  199. case AFADD: t = AFADDCC; break;
  200. case AFADDS: t = AFADDSCC; break;
  201. case AFCTIW: t = AFCTIWCC; break;
  202. case AFCTIWZ: t = AFCTIWZCC; break;
  203. case AFDIV: t = AFDIVCC; break;
  204. case AFDIVS: t = AFDIVSCC; break;
  205. case AFMADD: t = AFMADDCC; break;
  206. case AFMADDS: t = AFMADDSCC; break;
  207. case AFMOVD: t = AFMOVDCC; break;
  208. case AFMSUB: t = AFMSUBCC; break;
  209. case AFMSUBS: t = AFMSUBSCC; break;
  210. case AFMUL: t = AFMULCC; break;
  211. case AFMULS: t = AFMULSCC; break;
  212. case AFNABS: t = AFNABSCC; break;
  213. case AFNEG: t = AFNEGCC; break;
  214. case AFNMADD: t = AFNMADDCC; break;
  215. case AFNMADDS: t = AFNMADDSCC; break;
  216. case AFNMSUB: t = AFNMSUBCC; break;
  217. case AFNMSUBS: t = AFNMSUBSCC; break;
  218. case AFRSP: t = AFRSPCC; break;
  219. case AFSUB: t = AFSUBCC; break;
  220. case AFSUBS: t = AFSUBSCC; break;
  221. case ACNTLZW: t = ACNTLZWCC; break;
  222. case AMTFSB0: t = AMTFSB0CC; break;
  223. case AMTFSB1: t = AMTFSB1CC; break;
  224. */
  225. case AADD: t = AADDCC; break;
  226. case AADDV: t = AADDVCC; break;
  227. case AADDC: t = AADDCCC; break;
  228. case AADDCV: t = AADDCVCC; break;
  229. case AADDME: t = AADDMECC; break;
  230. case AADDMEV: t = AADDMEVCC; break;
  231. case AADDE: t = AADDECC; break;
  232. case AADDEV: t = AADDEVCC; break;
  233. case AADDZE: t = AADDZECC; break;
  234. case AADDZEV: t = AADDZEVCC; break;
  235. case AAND: t = AANDCC; break;
  236. case AANDN: t = AANDNCC; break;
  237. case ADIVW: t = ADIVWCC; break;
  238. case ADIVWV: t = ADIVWVCC; break;
  239. case ADIVWU: t = ADIVWUCC; break;
  240. case ADIVWUV: t = ADIVWUVCC; break;
  241. case ADIVD: t = ADIVDCC; break;
  242. case ADIVDV: t = ADIVDVCC; break;
  243. case ADIVDU: t = ADIVDUCC; break;
  244. case ADIVDUV: t = ADIVDUVCC; break;
  245. case AEQV: t = AEQVCC; break;
  246. case AEXTSB: t = AEXTSBCC; break;
  247. case AEXTSH: t = AEXTSHCC; break;
  248. case AEXTSW: t = AEXTSWCC; break;
  249. case AMULHW: t = AMULHWCC; break;
  250. case AMULHWU: t = AMULHWUCC; break;
  251. case AMULLW: t = AMULLWCC; break;
  252. case AMULLWV: t = AMULLWVCC; break;
  253. case AMULHD: t = AMULHDCC; break;
  254. case AMULHDU: t = AMULHDUCC; break;
  255. case AMULLD: t = AMULLDCC; break;
  256. case AMULLDV: t = AMULLDVCC; break;
  257. case ANAND: t = ANANDCC; break;
  258. case ANEG: t = ANEGCC; break;
  259. case ANEGV: t = ANEGVCC; break;
  260. case ANOR: t = ANORCC; break;
  261. case AOR: t = AORCC; break;
  262. case AORN: t = AORNCC; break;
  263. case AREM: t = AREMCC; break;
  264. case AREMV: t = AREMVCC; break;
  265. case AREMU: t = AREMUCC; break;
  266. case AREMUV: t = AREMUVCC; break;
  267. case AREMD: t = AREMDCC; break;
  268. case AREMDV: t = AREMDVCC; break;
  269. case AREMDU: t = AREMDUCC; break;
  270. case AREMDUV: t = AREMDUVCC; break;
  271. case ARLWMI: t = ARLWMICC; break;
  272. case ARLWNM: t = ARLWNMCC; break;
  273. case ASLW: t = ASLWCC; break;
  274. case ASRAW: t = ASRAWCC; break;
  275. case ASRW: t = ASRWCC; break;
  276. case ASLD: t = ASLDCC; break;
  277. case ASRAD: t = ASRADCC; break;
  278. case ASRD: t = ASRDCC; break;
  279. case ASUB: t = ASUBCC; break;
  280. case ASUBV: t = ASUBVCC; break;
  281. case ASUBC: t = ASUBCCC; break;
  282. case ASUBCV: t = ASUBCVCC; break;
  283. case ASUBME: t = ASUBMECC; break;
  284. case ASUBMEV: t = ASUBMEVCC; break;
  285. case ASUBE: t = ASUBECC; break;
  286. case ASUBEV: t = ASUBEVCC; break;
  287. case ASUBZE: t = ASUBZECC; break;
  288. case ASUBZEV: t = ASUBZEVCC; break;
  289. case AXOR: t = AXORCC; break;
  290. break;
  291. }
  292. if(debug['D'])
  293. print("cmp %P; %P -> ", p1, p);
  294. p1->as = t;
  295. if(debug['D'])
  296. print("%P\n", p1);
  297. excise(r);
  298. continue;
  299. }
  300. }
  301. }
  302. void
  303. excise(Reg *r)
  304. {
  305. Prog *p;
  306. p = r->prog;
  307. p->as = ANOP;
  308. p->from = zprog.from;
  309. p->from3 = zprog.from3;
  310. p->to = zprog.to;
  311. p->reg = zprog.reg; /**/
  312. }
  313. Reg*
  314. uniqp(Reg *r)
  315. {
  316. Reg *r1;
  317. r1 = r->p1;
  318. if(r1 == R) {
  319. r1 = r->p2;
  320. if(r1 == R || r1->p2link != R)
  321. return R;
  322. } else
  323. if(r->p2 != R)
  324. return R;
  325. return r1;
  326. }
  327. Reg*
  328. uniqs(Reg *r)
  329. {
  330. Reg *r1;
  331. r1 = r->s1;
  332. if(r1 == R) {
  333. r1 = r->s2;
  334. if(r1 == R)
  335. return R;
  336. } else
  337. if(r->s2 != R)
  338. return R;
  339. return r1;
  340. }
  341. /*
  342. * if the system forces R0 to be zero,
  343. * convert references to $0 to references to R0.
  344. */
  345. regzer(Adr *a)
  346. {
  347. if(R0ISZERO) {
  348. if(a->type == D_CONST)
  349. if(a->sym == S)
  350. if(a->offset == 0)
  351. return 1;
  352. if(a->type == D_REG)
  353. if(a->reg == REGZERO)
  354. return 1;
  355. }
  356. return 0;
  357. }
  358. regtyp(Adr *a)
  359. {
  360. if(a->type == D_REG) {
  361. if(!R0ISZERO || a->reg != REGZERO)
  362. return 1;
  363. return 0;
  364. }
  365. if(a->type == D_FREG)
  366. return 1;
  367. return 0;
  368. }
  369. /*
  370. * the idea is to substitute
  371. * one register for another
  372. * from one MOV to another
  373. * MOV a, R0
  374. * ADD b, R0 / no use of R1
  375. * MOV R0, R1
  376. * would be converted to
  377. * MOV a, R1
  378. * ADD b, R1
  379. * MOV R1, R0
  380. * hopefully, then the former or latter MOV
  381. * will be eliminated by copy propagation.
  382. */
  383. int
  384. subprop(Reg *r0)
  385. {
  386. Prog *p;
  387. Adr *v1, *v2;
  388. Reg *r;
  389. int t;
  390. p = r0->prog;
  391. v1 = &p->from;
  392. if(!regtyp(v1))
  393. return 0;
  394. v2 = &p->to;
  395. if(!regtyp(v2))
  396. return 0;
  397. for(r=uniqp(r0); r!=R; r=uniqp(r)) {
  398. if(uniqs(r) == R)
  399. break;
  400. p = r->prog;
  401. switch(p->as) {
  402. case ABL:
  403. return 0;
  404. case AADD:
  405. case AADDC:
  406. case AADDCC:
  407. case AADDE:
  408. case AADDECC:
  409. case ASUB:
  410. case ASUBCC:
  411. case ASUBC:
  412. case ASUBCCC:
  413. case ASUBE:
  414. case ASUBECC:
  415. case ASLW:
  416. case ASRW:
  417. case ASRWCC:
  418. case ASRAW:
  419. case ASRAWCC:
  420. case ASLD:
  421. case ASRD:
  422. case ASRAD:
  423. case AOR:
  424. case AORCC:
  425. case AORN:
  426. case AORNCC:
  427. case AAND:
  428. case AANDCC:
  429. case AANDN:
  430. case AANDNCC:
  431. case ANAND:
  432. case ANANDCC:
  433. case ANOR:
  434. case ANORCC:
  435. case AXOR:
  436. case AXORCC:
  437. case AMULHW:
  438. case AMULHWU:
  439. case AMULLW:
  440. case AMULLD:
  441. case ADIVW:
  442. case ADIVWU:
  443. case ADIVD:
  444. case ADIVDU:
  445. case AREM:
  446. case AREMU:
  447. case AREMD:
  448. case AREMDU:
  449. case ARLWNM:
  450. case ARLWNMCC:
  451. case AFADD:
  452. case AFADDS:
  453. case AFSUB:
  454. case AFSUBS:
  455. case AFMUL:
  456. case AFMULS:
  457. case AFDIV:
  458. case AFDIVS:
  459. if(p->to.type == v1->type)
  460. if(p->to.reg == v1->reg) {
  461. if(p->reg == NREG)
  462. p->reg = p->to.reg;
  463. goto gotit;
  464. }
  465. break;
  466. case AADDME:
  467. case AADDMECC:
  468. case AADDZE:
  469. case AADDZECC:
  470. case ASUBME:
  471. case ASUBMECC:
  472. case ASUBZE:
  473. case ASUBZECC:
  474. case ANEG:
  475. case ANEGCC:
  476. case AFNEG:
  477. case AFNEGCC:
  478. case AFMOVS:
  479. case AFMOVD:
  480. case AMOVW:
  481. case AMOVD:
  482. if(p->to.type == v1->type)
  483. if(p->to.reg == v1->reg)
  484. goto gotit;
  485. break;
  486. }
  487. if(copyau(&p->from, v2) ||
  488. copyau1(p, v2) ||
  489. copyau(&p->to, v2))
  490. break;
  491. if(copysub(&p->from, v1, v2, 0) ||
  492. copysub1(p, v1, v2, 0) ||
  493. copysub(&p->to, v1, v2, 0))
  494. break;
  495. }
  496. return 0;
  497. gotit:
  498. copysub(&p->to, v1, v2, 1);
  499. if(debug['P']) {
  500. print("gotit: %D->%D\n%P", v1, v2, r->prog);
  501. if(p->from.type == v2->type)
  502. print(" excise");
  503. print("\n");
  504. }
  505. for(r=uniqs(r); r!=r0; r=uniqs(r)) {
  506. p = r->prog;
  507. copysub(&p->from, v1, v2, 1);
  508. copysub1(p, v1, v2, 1);
  509. copysub(&p->to, v1, v2, 1);
  510. if(debug['P'])
  511. print("%P\n", r->prog);
  512. }
  513. t = v1->reg;
  514. v1->reg = v2->reg;
  515. v2->reg = t;
  516. if(debug['P'])
  517. print("%P last\n", r->prog);
  518. return 1;
  519. }
  520. /*
  521. * The idea is to remove redundant copies.
  522. * v1->v2 F=0
  523. * (use v2 s/v2/v1/)*
  524. * set v1 F=1
  525. * use v2 return fail
  526. * -----------------
  527. * v1->v2 F=0
  528. * (use v2 s/v2/v1/)*
  529. * set v1 F=1
  530. * set v2 return success
  531. */
  532. int
  533. copyprop(Reg *r0)
  534. {
  535. Prog *p;
  536. Adr *v1, *v2;
  537. Reg *r;
  538. p = r0->prog;
  539. v1 = &p->from;
  540. v2 = &p->to;
  541. if(copyas(v1, v2))
  542. return 1;
  543. for(r=firstr; r!=R; r=r->link)
  544. r->active = 0;
  545. return copy1(v1, v2, r0->s1, 0);
  546. }
  547. copy1(Adr *v1, Adr *v2, Reg *r, int f)
  548. {
  549. int t;
  550. Prog *p;
  551. if(r->active) {
  552. if(debug['P'])
  553. print("act set; return 1\n");
  554. return 1;
  555. }
  556. r->active = 1;
  557. if(debug['P'])
  558. print("copy %D->%D f=%d\n", v1, v2, f);
  559. for(; r != R; r = r->s1) {
  560. p = r->prog;
  561. if(debug['P'])
  562. print("%P", p);
  563. if(!f && uniqp(r) == R) {
  564. f = 1;
  565. if(debug['P'])
  566. print("; merge; f=%d", f);
  567. }
  568. t = copyu(p, v2, A);
  569. switch(t) {
  570. case 2: /* rar, cant split */
  571. if(debug['P'])
  572. print("; %Drar; return 0\n", v2);
  573. return 0;
  574. case 3: /* set */
  575. if(debug['P'])
  576. print("; %Dset; return 1\n", v2);
  577. return 1;
  578. case 1: /* used, substitute */
  579. case 4: /* use and set */
  580. if(f) {
  581. if(!debug['P'])
  582. return 0;
  583. if(t == 4)
  584. print("; %Dused+set and f=%d; return 0\n", v2, f);
  585. else
  586. print("; %Dused and f=%d; return 0\n", v2, f);
  587. return 0;
  588. }
  589. if(copyu(p, v2, v1)) {
  590. if(debug['P'])
  591. print("; sub fail; return 0\n");
  592. return 0;
  593. }
  594. if(debug['P'])
  595. print("; sub%D/%D", v2, v1);
  596. if(t == 4) {
  597. if(debug['P'])
  598. print("; %Dused+set; return 1\n", v2);
  599. return 1;
  600. }
  601. break;
  602. }
  603. if(!f) {
  604. t = copyu(p, v1, A);
  605. if(!f && (t == 2 || t == 3 || t == 4)) {
  606. f = 1;
  607. if(debug['P'])
  608. print("; %Dset and !f; f=%d", v1, f);
  609. }
  610. }
  611. if(debug['P'])
  612. print("\n");
  613. if(r->s2)
  614. if(!copy1(v1, v2, r->s2, f))
  615. return 0;
  616. }
  617. return 1;
  618. }
  619. /*
  620. * return
  621. * 1 if v only used (and substitute),
  622. * 2 if read-alter-rewrite
  623. * 3 if set
  624. * 4 if set and used
  625. * 0 otherwise (not touched)
  626. */
  627. int
  628. copyu(Prog *p, Adr *v, Adr *s)
  629. {
  630. switch(p->as) {
  631. default:
  632. if(debug['P'])
  633. print(" (???)");
  634. return 2;
  635. case ANOP: /* read, write */
  636. case AMOVH:
  637. case AMOVHZ:
  638. case AMOVB:
  639. case AMOVBZ:
  640. case AMOVW:
  641. case AMOVWZ:
  642. case AMOVD:
  643. case ANEG:
  644. case ANEGCC:
  645. case AADDME:
  646. case AADDMECC:
  647. case AADDZE:
  648. case AADDZECC:
  649. case ASUBME:
  650. case ASUBMECC:
  651. case ASUBZE:
  652. case ASUBZECC:
  653. case AFCTIW:
  654. case AFCTIWZ:
  655. case AFMOVS:
  656. case AFMOVD:
  657. case AFRSP:
  658. case AFNEG:
  659. case AFNEGCC:
  660. if(s != A) {
  661. if(copysub(&p->from, v, s, 1))
  662. return 1;
  663. if(!copyas(&p->to, v))
  664. if(copysub(&p->to, v, s, 1))
  665. return 1;
  666. return 0;
  667. }
  668. if(copyas(&p->to, v)) {
  669. if(copyau(&p->from, v))
  670. return 4;
  671. return 3;
  672. }
  673. if(copyau(&p->from, v))
  674. return 1;
  675. if(copyau(&p->to, v))
  676. return 1;
  677. return 0;
  678. case ARLWMI: /* read read rar */
  679. case ARLWMICC:
  680. if(copyas(&p->to, v))
  681. return 2;
  682. /* fall through */
  683. case AADD: /* read read write */
  684. case AADDC:
  685. case AADDE:
  686. case ASUB:
  687. case ASLW:
  688. case ASRW:
  689. case ASRAW:
  690. case ASLD:
  691. case ASRD:
  692. case ASRAD:
  693. case AOR:
  694. case AORCC:
  695. case AORN:
  696. case AORNCC:
  697. case AAND:
  698. case AANDCC:
  699. case AANDN:
  700. case AANDNCC:
  701. case ANAND:
  702. case ANANDCC:
  703. case ANOR:
  704. case ANORCC:
  705. case AXOR:
  706. case AMULHW:
  707. case AMULHWU:
  708. case AMULLW:
  709. case AMULLD:
  710. case ADIVW:
  711. case ADIVD:
  712. case ADIVWU:
  713. case ADIVDU:
  714. case AREM:
  715. case AREMU:
  716. case AREMD:
  717. case AREMDU:
  718. case ARLWNM:
  719. case ARLWNMCC:
  720. case AFADDS:
  721. case AFADD:
  722. case AFSUBS:
  723. case AFSUB:
  724. case AFMULS:
  725. case AFMUL:
  726. case AFDIVS:
  727. case AFDIV:
  728. if(s != A) {
  729. if(copysub(&p->from, v, s, 1))
  730. return 1;
  731. if(copysub1(p, v, s, 1))
  732. return 1;
  733. if(!copyas(&p->to, v))
  734. if(copysub(&p->to, v, s, 1))
  735. return 1;
  736. return 0;
  737. }
  738. if(copyas(&p->to, v)) {
  739. if(p->reg == NREG)
  740. p->reg = p->to.reg;
  741. if(copyau(&p->from, v))
  742. return 4;
  743. if(copyau1(p, v))
  744. return 4;
  745. return 3;
  746. }
  747. if(copyau(&p->from, v))
  748. return 1;
  749. if(copyau1(p, v))
  750. return 1;
  751. if(copyau(&p->to, v))
  752. return 1;
  753. return 0;
  754. case ABEQ:
  755. case ABGT:
  756. case ABGE:
  757. case ABLT:
  758. case ABLE:
  759. case ABNE:
  760. case ABVC:
  761. case ABVS:
  762. break;
  763. case ACMP: /* read read */
  764. case ACMPU:
  765. case ACMPW:
  766. case ACMPWU:
  767. case AFCMPO:
  768. case AFCMPU:
  769. if(s != A) {
  770. if(copysub(&p->from, v, s, 1))
  771. return 1;
  772. return copysub(&p->to, v, s, 1);
  773. }
  774. if(copyau(&p->from, v))
  775. return 1;
  776. if(copyau(&p->to, v))
  777. return 1;
  778. break;
  779. case ABR: /* funny */
  780. if(s != A) {
  781. if(copysub(&p->to, v, s, 1))
  782. return 1;
  783. return 0;
  784. }
  785. if(copyau(&p->to, v))
  786. return 1;
  787. return 0;
  788. case ARETURN: /* funny */
  789. if(v->type == D_REG)
  790. if(v->reg == REGRET)
  791. return 2;
  792. if(v->type == D_FREG)
  793. if(v->reg == FREGRET)
  794. return 2;
  795. case ABL: /* funny */
  796. if(v->type == D_REG) {
  797. if(v->reg <= REGEXT && v->reg > exregoffset)
  798. return 2;
  799. if(v->reg == REGARG)
  800. return 2;
  801. }
  802. if(v->type == D_FREG) {
  803. if(v->reg <= FREGEXT && v->reg > exfregoffset)
  804. return 2;
  805. }
  806. if(s != A) {
  807. if(copysub(&p->to, v, s, 1))
  808. return 1;
  809. return 0;
  810. }
  811. if(copyau(&p->to, v))
  812. return 4;
  813. return 3;
  814. case ATEXT: /* funny */
  815. if(v->type == D_REG)
  816. if(v->reg == REGARG)
  817. return 3;
  818. return 0;
  819. }
  820. return 0;
  821. }
  822. int
  823. a2type(Prog *p)
  824. {
  825. switch(p->as) {
  826. case AADD:
  827. case AADDC:
  828. case AADDCC:
  829. case AADDCCC:
  830. case AADDE:
  831. case AADDECC:
  832. case AADDME:
  833. case AADDMECC:
  834. case AADDZE:
  835. case AADDZECC:
  836. case ASUB:
  837. case ASUBC:
  838. case ASUBCC:
  839. case ASUBCCC:
  840. case ASUBE:
  841. case ASUBECC:
  842. case ASUBME:
  843. case ASUBMECC:
  844. case ASUBZE:
  845. case ASUBZECC:
  846. case ASLW:
  847. case ASLWCC:
  848. case ASRW:
  849. case ASRWCC:
  850. case ASRAW:
  851. case ASRAWCC:
  852. case ASLD:
  853. case ASLDCC:
  854. case ASRD:
  855. case ASRDCC:
  856. case ASRAD:
  857. case ASRADCC:
  858. case AOR:
  859. case AORCC:
  860. case AORN:
  861. case AORNCC:
  862. case AAND:
  863. case AANDCC:
  864. case AANDN:
  865. case AANDNCC:
  866. case AXOR:
  867. case AXORCC:
  868. case ANEG:
  869. case ANEGCC:
  870. case AMULHW:
  871. case AMULHWU:
  872. case AMULLW:
  873. case AMULLWCC:
  874. case ADIVW:
  875. case ADIVWCC:
  876. case ADIVWU:
  877. case ADIVWUCC:
  878. case AREM:
  879. case AREMCC:
  880. case AREMU:
  881. case AREMUCC:
  882. case AMULLD:
  883. case AMULLDCC:
  884. case ADIVD:
  885. case ADIVDCC:
  886. case ADIVDU:
  887. case ADIVDUCC:
  888. case AREMD:
  889. case AREMDCC:
  890. case AREMDU:
  891. case AREMDUCC:
  892. case ANAND:
  893. case ANANDCC:
  894. case ANOR:
  895. case ANORCC:
  896. case ARLWMI:
  897. case ARLWMICC:
  898. case ARLWNM:
  899. case ARLWNMCC:
  900. return D_REG;
  901. case AFADDS:
  902. case AFADDSCC:
  903. case AFADD:
  904. case AFADDCC:
  905. case AFSUBS:
  906. case AFSUBSCC:
  907. case AFSUB:
  908. case AFSUBCC:
  909. case AFMULS:
  910. case AFMULSCC:
  911. case AFMUL:
  912. case AFMULCC:
  913. case AFDIVS:
  914. case AFDIVSCC:
  915. case AFDIV:
  916. case AFDIVCC:
  917. case AFNEG:
  918. case AFNEGCC:
  919. return D_FREG;
  920. }
  921. return D_NONE;
  922. }
  923. /*
  924. * direct reference,
  925. * could be set/use depending on
  926. * semantics
  927. */
  928. int
  929. copyas(Adr *a, Adr *v)
  930. {
  931. if(regtyp(v))
  932. if(a->type == v->type)
  933. if(a->reg == v->reg)
  934. return 1;
  935. return 0;
  936. }
  937. /*
  938. * either direct or indirect
  939. */
  940. int
  941. copyau(Adr *a, Adr *v)
  942. {
  943. if(copyas(a, v))
  944. return 1;
  945. if(v->type == D_REG)
  946. if(a->type == D_OREG)
  947. if(v->reg == a->reg)
  948. return 1;
  949. return 0;
  950. }
  951. int
  952. copyau1(Prog *p, Adr *v)
  953. {
  954. if(regtyp(v))
  955. if(p->from.type == v->type || p->to.type == v->type)
  956. if(p->reg == v->reg) {
  957. if(a2type(p) != v->type)
  958. print("botch a2type %P\n", p);
  959. return 1;
  960. }
  961. return 0;
  962. }
  963. /*
  964. * substitute s for v in a
  965. * return failure to substitute
  966. */
  967. int
  968. copysub(Adr *a, Adr *v, Adr *s, int f)
  969. {
  970. if(f)
  971. if(copyau(a, v))
  972. a->reg = s->reg;
  973. return 0;
  974. }
  975. int
  976. copysub1(Prog *p1, Adr *v, Adr *s, int f)
  977. {
  978. if(f)
  979. if(copyau1(p1, v))
  980. p1->reg = s->reg;
  981. return 0;
  982. }