peep.c 15 KB

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