peep.c 16 KB

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