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