10 * complete R structure
13 for(r=firstr; r!=R; r=r1) {
44 for(r=firstr; r!=R; r=r->link) {
46 if(p->as == AMOVW || p->as == AFMOVS || p->as == AFMOVD)
49 if(p->from.type == p->to.type) {
54 if(subprop(r) && copyprop(r)) {
60 if(p->to.type == D_REG) {
62 p->from.reg = REGZERO;
67 if(subprop(r) && copyprop(r)) {
77 * look for MOVB x,R; MOVB R,R
79 for(r=firstr; r!=R; r=r->link) {
88 if(p->to.type != D_REG)
98 if(p1->from.type != D_REG || p1->from.reg != p->to.reg)
100 if(p1->to.type != D_REG || p1->to.reg != p->to.reg)
106 return; /* allow following code improvement to be suppressed */
109 * look for OP x,y,R; CMP R, $0 -> OPCC x,y,R
110 * when OP can set condition codes correctly
112 for(r=firstr; r!=R; r=r->link) {
121 switch(r1->prog->as) {
126 /* the conditions can be complex and these are currently little used */
141 while (r1 != R && r1->prog->as == ANOP);
145 if(p1->to.type != D_REG || p1->to.reg != p->from.reg)
152 /* irregular instructions */
153 if(p1->from.type == D_CONST)
161 if(p1->from.type != D_REG)
182 /* don't deal with floating point instructions for now */
184 case AFABS: t = AFABSCC; break;
185 case AFADD: t = AFADDCC; break;
186 case AFADDS: t = AFADDSCC; break;
187 case AFCTIW: t = AFCTIWCC; break;
188 case AFCTIWZ: t = AFCTIWZCC; break;
189 case AFDIV: t = AFDIVCC; break;
190 case AFDIVS: t = AFDIVSCC; break;
191 case AFMADD: t = AFMADDCC; break;
192 case AFMADDS: t = AFMADDSCC; break;
193 case AFMOVD: t = AFMOVDCC; break;
194 case AFMSUB: t = AFMSUBCC; break;
195 case AFMSUBS: t = AFMSUBSCC; break;
196 case AFMUL: t = AFMULCC; break;
197 case AFMULS: t = AFMULSCC; break;
198 case AFNABS: t = AFNABSCC; break;
199 case AFNEG: t = AFNEGCC; break;
200 case AFNMADD: t = AFNMADDCC; break;
201 case AFNMADDS: t = AFNMADDSCC; break;
202 case AFNMSUB: t = AFNMSUBCC; break;
203 case AFNMSUBS: t = AFNMSUBSCC; break;
204 case AFRSP: t = AFRSPCC; break;
205 case AFSUB: t = AFSUBCC; break;
206 case AFSUBS: t = AFSUBSCC; break;
207 case ACNTLZW: t = ACNTLZWCC; break;
208 case AMTFSB0: t = AMTFSB0CC; break;
209 case AMTFSB1: t = AMTFSB1CC; break;
211 case AADD: t = AADDCC; break;
212 case AADDV: t = AADDVCC; break;
213 case AADDC: t = AADDCCC; break;
214 case AADDCV: t = AADDCVCC; break;
215 case AADDME: t = AADDMECC; break;
216 case AADDMEV: t = AADDMEVCC; break;
217 case AADDE: t = AADDECC; break;
218 case AADDEV: t = AADDEVCC; break;
219 case AADDZE: t = AADDZECC; break;
220 case AADDZEV: t = AADDZEVCC; break;
221 case AAND: t = AANDCC; break;
222 case AANDN: t = AANDNCC; break;
223 case ADIVW: t = ADIVWCC; break;
224 case ADIVWV: t = ADIVWVCC; break;
225 case ADIVWU: t = ADIVWUCC; break;
226 case ADIVWUV: t = ADIVWUVCC; break;
227 case AEQV: t = AEQVCC; break;
228 case AEXTSB: t = AEXTSBCC; break;
229 case AEXTSH: t = AEXTSHCC; break;
230 case AMULHW: t = AMULHWCC; break;
231 case AMULHWU: t = AMULHWUCC; break;
232 case AMULLW: t = AMULLWCC; break;
233 case AMULLWV: t = AMULLWVCC; break;
234 case ANAND: t = ANANDCC; break;
235 case ANEG: t = ANEGCC; break;
236 case ANEGV: t = ANEGVCC; break;
237 case ANOR: t = ANORCC; break;
238 case AOR: t = AORCC; break;
239 case AORN: t = AORNCC; break;
240 case AREM: t = AREMCC; break;
241 case AREMV: t = AREMVCC; break;
242 case AREMU: t = AREMUCC; break;
243 case AREMUV: t = AREMUVCC; break;
244 case ARLWMI: t = ARLWMICC; break;
245 case ARLWNM: t = ARLWNMCC; break;
246 case ASLW: t = ASLWCC; break;
247 case ASRAW: t = ASRAWCC; break;
248 case ASRW: t = ASRWCC; break;
249 case ASUB: t = ASUBCC; break;
250 case ASUBV: t = ASUBVCC; break;
251 case ASUBC: t = ASUBCCC; break;
252 case ASUBCV: t = ASUBCVCC; break;
253 case ASUBME: t = ASUBMECC; break;
254 case ASUBMEV: t = ASUBMEVCC; break;
255 case ASUBE: t = ASUBECC; break;
256 case ASUBEV: t = ASUBEVCC; break;
257 case ASUBZE: t = ASUBZECC; break;
258 case ASUBZEV: t = ASUBZEVCC; break;
259 case AXOR: t = AXORCC; break;
263 print("cmp %P; %P -> ", p1, p);
280 p->from = zprog.from;
281 p->from3 = zprog.from3;
283 p->reg = zprog.reg; /**/
294 if(r1 == R || r1->p2link != R)
319 * if the system forces R0 to be zero,
320 * convert references to $0 to references to R0.
325 if(a->type == D_CONST)
330 if(a->reg == REGZERO)
339 if(a->type == D_REG) {
340 if(!R0ISZERO || a->reg != REGZERO)
344 if(a->type == D_FREG)
350 * the idea is to substitute
351 * one register for another
352 * from one MOV to another
354 * ADD b, R0 / no use of R1
356 * would be converted to
360 * hopefully, then the former or latter MOV
361 * will be eliminated by copy propagation.
378 for(r=uniqp(r0); r!=R; r=uniqp(r)) {
435 if(p->to.type == v1->type)
436 if(p->to.reg == v1->reg) {
458 if(p->to.type == v1->type)
459 if(p->to.reg == v1->reg)
463 if(copyau(&p->from, v2) ||
467 if(copysub(&p->from, v1, v2, 0) ||
468 copysub1(p, v1, v2, 0) ||
469 copysub(&p->to, v1, v2, 0))
475 copysub(&p->to, v1, v2, 1);
477 print("gotit: %D->%D\n%P", v1, v2, r->prog);
478 if(p->from.type == v2->type)
482 for(r=uniqs(r); r!=r0; r=uniqs(r)) {
484 copysub(&p->from, v1, v2, 1);
485 copysub1(p, v1, v2, 1);
486 copysub(&p->to, v1, v2, 1);
488 print("%P\n", r->prog);
494 print("%P last\n", r->prog);
499 * The idea is to remove redundant copies.
508 * set v2 return success
522 for(r=firstr; r!=R; r=r->link)
524 return copy1(v1, v2, r0->s1, 0);
527 copy1(Adr *v1, Adr *v2, Reg *r, int f)
534 print("act set; return 1\n");
539 print("copy %D->%D f=%d\n", v1, v2, f);
540 for(; r != R; r = r->s1) {
544 if(!f && uniqp(r) == R) {
547 print("; merge; f=%d", f);
551 case 2: /* rar, cant split */
553 print("; %Drar; return 0\n", v2);
558 print("; %Dset; return 1\n", v2);
561 case 1: /* used, substitute */
562 case 4: /* use and set */
567 print("; %Dused+set and f=%d; return 0\n", v2, f);
569 print("; %Dused and f=%d; return 0\n", v2, f);
572 if(copyu(p, v2, v1)) {
574 print("; sub fail; return 0\n");
578 print("; sub%D/%D", v2, v1);
581 print("; %Dused+set; return 1\n", v2);
588 if(!f && (t == 2 || t == 3 || t == 4)) {
591 print("; %Dset and !f; f=%d", v1, f);
597 if(!copy1(v1, v2, r->s2, f))
605 * 1 if v only used (and substitute),
606 * 2 if read-alter-rewrite
609 * 0 otherwise (not touched)
612 copyu(Prog *p, Adr *v, Adr *s)
622 case ANOP: /* read, write */
648 if(copysub(&p->from, v, s, 1))
650 if(!copyas(&p->to, v))
651 if(copysub(&p->to, v, s, 1))
655 if(copyas(&p->to, v)) {
656 if(copyau(&p->from, v))
660 if(copyau(&p->from, v))
662 if(copyau(&p->to, v))
666 case ARLWMI: /* read read rar */
668 if(copyas(&p->to, v))
672 case AADD: /* read read write */
711 if(copysub(&p->from, v, s, 1))
713 if(copysub1(p, v, s, 1))
715 if(!copyas(&p->to, v))
716 if(copysub(&p->to, v, s, 1))
720 if(copyas(&p->to, v)) {
723 if(copyau(&p->from, v))
729 if(copyau(&p->from, v))
733 if(copyau(&p->to, v))
747 case ACMP: /* read read */
752 if(copysub(&p->from, v, s, 1))
754 return copysub(&p->to, v, s, 1);
756 if(copyau(&p->from, v))
758 if(copyau(&p->to, v))
762 case ABR: /* funny */
764 if(copysub(&p->to, v, s, 1))
768 if(copyau(&p->to, v))
772 case ARETURN: /* funny */
776 if(v->type == D_FREG)
777 if(v->reg == FREGRET)
780 case ABL: /* funny */
781 if(v->type == D_REG) {
782 if(v->reg <= REGEXT && v->reg > exregoffset)
787 if(v->type == D_FREG) {
788 if(v->reg <= FREGEXT && v->reg > exfregoffset)
793 if(copysub(&p->to, v, s, 1))
797 if(copyau(&p->to, v))
801 case ATEXT: /* funny */
900 * could be set/use depending on
904 copyas(Adr *a, Adr *v)
908 if(a->type == v->type)
915 * either direct or indirect
918 copyau(Adr *a, Adr *v)
924 if(a->type == D_OREG)
931 copyau1(Prog *p, Adr *v)
935 if(p->from.type == v->type || p->to.type == v->type)
936 if(p->reg == v->reg) {
937 if(a2type(p) != v->type)
938 print("botch a2type %P\n", p);
945 * substitute s for v in a
946 * return failure to substitute
949 copysub(Adr *a, Adr *v, Adr *s, int f)
959 copysub1(Prog *p1, Adr *v, Adr *s, int f)