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 case ARLWMI: 427 case ARLWMICC: 428 429 case AFADD: 430 case AFADDS: 431 case AFSUB: 432 case AFSUBS: 433 case AFMUL: 434 case AFMULS: 435 case AFDIV: 436 case AFDIVS: 437 if(p->to.type == v1->type) 438 if(p->to.reg == v1->reg) { 439 if(p->reg == NREG) 440 p->reg = p->to.reg; 441 goto gotit; 442 } 443 break; 444 445 case AADDME: 446 case AADDMECC: 447 case AADDZE: 448 case AADDZECC: 449 case ASUBME: 450 case ASUBMECC: 451 case ASUBZE: 452 case ASUBZECC: 453 case ANEG: 454 case ANEGCC: 455 case AFNEG: 456 case AFNEGCC: 457 case AFMOVS: 458 case AFMOVD: 459 case AMOVW: 460 if(p->to.type == v1->type) 461 if(p->to.reg == v1->reg) 462 goto gotit; 463 break; 464 } 465 if(copyau(&p->from, v2) || 466 copyau1(p, v2) || 467 copyau(&p->to, v2)) 468 break; 469 if(copysub(&p->from, v1, v2, 0) || 470 copysub1(p, v1, v2, 0) || 471 copysub(&p->to, v1, v2, 0)) 472 break; 473 } 474 return 0; 475 476 gotit: 477 copysub(&p->to, v1, v2, 1); 478 if(debug['P']) { 479 print("gotit: %D->%D\n%P", v1, v2, r->prog); 480 if(p->from.type == v2->type) 481 print(" excise"); 482 print("\n"); 483 } 484 for(r=uniqs(r); r!=r0; r=uniqs(r)) { 485 p = r->prog; 486 copysub(&p->from, v1, v2, 1); 487 copysub1(p, v1, v2, 1); 488 copysub(&p->to, v1, v2, 1); 489 if(debug['P']) 490 print("%P\n", r->prog); 491 } 492 t = v1->reg; 493 v1->reg = v2->reg; 494 v2->reg = t; 495 if(debug['P']) 496 print("%P last\n", r->prog); 497 return 1; 498 } 499 500 /* 501 * The idea is to remove redundant copies. 502 * v1->v2 F=0 503 * (use v2 s/v2/v1/)* 504 * set v1 F=1 505 * use v2 return fail 506 * ----------------- 507 * v1->v2 F=0 508 * (use v2 s/v2/v1/)* 509 * set v1 F=1 510 * set v2 return success 511 */ 512 int 513 copyprop(Reg *r0) 514 { 515 Prog *p; 516 Adr *v1, *v2; 517 Reg *r; 518 519 p = r0->prog; 520 v1 = &p->from; 521 v2 = &p->to; 522 if(copyas(v1, v2)) 523 return 1; 524 for(r=firstr; r!=R; r=r->link) 525 r->active = 0; 526 return copy1(v1, v2, r0->s1, 0); 527 } 528 529 copy1(Adr *v1, Adr *v2, Reg *r, int f) 530 { 531 int t; 532 Prog *p; 533 534 if(r->active) { 535 if(debug['P']) 536 print("act set; return 1\n"); 537 return 1; 538 } 539 r->active = 1; 540 if(debug['P']) 541 print("copy %D->%D f=%d\n", v1, v2, f); 542 for(; r != R; r = r->s1) { 543 p = r->prog; 544 if(debug['P']) 545 print("%P", p); 546 if(!f && uniqp(r) == R) { 547 f = 1; 548 if(debug['P']) 549 print("; merge; f=%d", f); 550 } 551 t = copyu(p, v2, A); 552 switch(t) { 553 case 2: /* rar, cant split */ 554 if(debug['P']) 555 print("; %Drar; return 0\n", v2); 556 return 0; 557 558 case 3: /* set */ 559 if(debug['P']) 560 print("; %Dset; return 1\n", v2); 561 return 1; 562 563 case 1: /* used, substitute */ 564 case 4: /* use and set */ 565 if(f) { 566 if(!debug['P']) 567 return 0; 568 if(t == 4) 569 print("; %Dused+set and f=%d; return 0\n", v2, f); 570 else 571 print("; %Dused and f=%d; return 0\n", v2, f); 572 return 0; 573 } 574 if(copyu(p, v2, v1)) { 575 if(debug['P']) 576 print("; sub fail; return 0\n"); 577 return 0; 578 } 579 if(debug['P']) 580 print("; sub%D/%D", v2, v1); 581 if(t == 4) { 582 if(debug['P']) 583 print("; %Dused+set; return 1\n", v2); 584 return 1; 585 } 586 break; 587 } 588 if(!f) { 589 t = copyu(p, v1, A); 590 if(!f && (t == 2 || t == 3 || t == 4)) { 591 f = 1; 592 if(debug['P']) 593 print("; %Dset and !f; f=%d", v1, f); 594 } 595 } 596 if(debug['P']) 597 print("\n"); 598 if(r->s2) 599 if(!copy1(v1, v2, r->s2, f)) 600 return 0; 601 } 602 return 1; 603 } 604 605 /* 606 * return 607 * 1 if v only used (and substitute), 608 * 2 if read-alter-rewrite 609 * 3 if set 610 * 4 if set and used 611 * 0 otherwise (not touched) 612 */ 613 int 614 copyu(Prog *p, Adr *v, Adr *s) 615 { 616 617 switch(p->as) { 618 619 default: 620 if(debug['P']) 621 print(" (???)"); 622 return 2; 623 624 625 case ANOP: /* read, write */ 626 case AMOVW: 627 case AMOVH: 628 case AMOVHZ: 629 case AMOVB: 630 case AMOVBZ: 631 632 case ANEG: 633 case ANEGCC: 634 case AADDME: 635 case AADDMECC: 636 case AADDZE: 637 case AADDZECC: 638 case ASUBME: 639 case ASUBMECC: 640 case ASUBZE: 641 case ASUBZECC: 642 643 case AFCTIW: 644 case AFCTIWZ: 645 case AFMOVS: 646 case AFMOVD: 647 case AFRSP: 648 case AFNEG: 649 case AFNEGCC: 650 if(s != A) { 651 if(copysub(&p->from, v, s, 1)) 652 return 1; 653 if(!copyas(&p->to, v)) 654 if(copysub(&p->to, v, s, 1)) 655 return 1; 656 return 0; 657 } 658 if(copyas(&p->to, v)) { 659 if(copyau(&p->from, v)) 660 return 4; 661 return 3; 662 } 663 if(copyau(&p->from, v)) 664 return 1; 665 if(copyau(&p->to, v)) 666 return 1; 667 return 0; 668 669 case AADD: /* read read write */ 670 case AADDC: 671 case AADDE: 672 case ASUB: 673 case ASLW: 674 case ASRW: 675 case ASRAW: 676 case AOR: 677 case AORCC: 678 case AORN: 679 case AORNCC: 680 case AAND: 681 case AANDCC: 682 case AANDN: 683 case AANDNCC: 684 case ANAND: 685 case ANANDCC: 686 case ANOR: 687 case ANORCC: 688 case AXOR: 689 case AMULHW: 690 case AMULHWU: 691 case AMULLW: 692 case ADIVW: 693 case ADIVWU: 694 case AREM: 695 case AREMU: 696 case ARLWMI: 697 case ARLWMICC: 698 case ARLWNM: 699 case ARLWNMCC: 700 701 case AFADDS: 702 case AFADD: 703 case AFSUBS: 704 case AFSUB: 705 case AFMULS: 706 case AFMUL: 707 case AFDIVS: 708 case AFDIV: 709 if(s != A) { 710 if(copysub(&p->from, v, s, 1)) 711 return 1; 712 if(copysub1(p, v, s, 1)) 713 return 1; 714 if(!copyas(&p->to, v)) 715 if(copysub(&p->to, v, s, 1)) 716 return 1; 717 return 0; 718 } 719 if(copyas(&p->to, v)) { 720 if(p->reg == NREG) 721 p->reg = p->to.reg; 722 if(copyau(&p->from, v)) 723 return 4; 724 if(copyau1(p, v)) 725 return 4; 726 return 3; 727 } 728 if(copyau(&p->from, v)) 729 return 1; 730 if(copyau1(p, v)) 731 return 1; 732 if(copyau(&p->to, v)) 733 return 1; 734 return 0; 735 736 case ABEQ: 737 case ABGT: 738 case ABGE: 739 case ABLT: 740 case ABLE: 741 case ABNE: 742 case ABVC: 743 case ABVS: 744 break; 745 746 case ACMP: /* read read */ 747 case ACMPU: 748 case AFCMPO: 749 case AFCMPU: 750 if(s != A) { 751 if(copysub(&p->from, v, s, 1)) 752 return 1; 753 return copysub(&p->to, v, s, 1); 754 } 755 if(copyau(&p->from, v)) 756 return 1; 757 if(copyau(&p->to, v)) 758 return 1; 759 break; 760 761 case ABR: /* funny */ 762 if(s != A) { 763 if(copysub(&p->to, v, s, 1)) 764 return 1; 765 return 0; 766 } 767 if(copyau(&p->to, v)) 768 return 1; 769 return 0; 770 771 case ARETURN: /* funny */ 772 if(v->type == D_REG) 773 if(v->reg == REGRET) 774 return 2; 775 if(v->type == D_FREG) 776 if(v->reg == FREGRET) 777 return 2; 778 779 case ABL: /* funny */ 780 if(v->type == D_REG) { 781 if(v->reg <= REGEXT && v->reg > exregoffset) 782 return 2; 783 if(v->reg == REGARG) 784 return 2; 785 } 786 if(v->type == D_FREG) { 787 if(v->reg <= FREGEXT && v->reg > exfregoffset) 788 return 2; 789 } 790 791 if(s != A) { 792 if(copysub(&p->to, v, s, 1)) 793 return 1; 794 return 0; 795 } 796 if(copyau(&p->to, v)) 797 return 4; 798 return 3; 799 800 case ATEXT: /* funny */ 801 if(v->type == D_REG) 802 if(v->reg == REGARG) 803 return 3; 804 return 0; 805 } 806 return 0; 807 } 808 809 int 810 a2type(Prog *p) 811 { 812 813 switch(p->as) { 814 case AADD: 815 case AADDC: 816 case AADDCC: 817 case AADDCCC: 818 case AADDE: 819 case AADDECC: 820 case AADDME: 821 case AADDMECC: 822 case AADDZE: 823 case AADDZECC: 824 case ASUB: 825 case ASUBC: 826 case ASUBCC: 827 case ASUBCCC: 828 case ASUBE: 829 case ASUBECC: 830 case ASUBME: 831 case ASUBMECC: 832 case ASUBZE: 833 case ASUBZECC: 834 case ASLW: 835 case ASLWCC: 836 case ASRW: 837 case ASRWCC: 838 case ASRAW: 839 case ASRAWCC: 840 case AOR: 841 case AORCC: 842 case AORN: 843 case AORNCC: 844 case AAND: 845 case AANDCC: 846 case AANDN: 847 case AANDNCC: 848 case AXOR: 849 case AXORCC: 850 case ANEG: 851 case ANEGCC: 852 case AMULHW: 853 case AMULHWU: 854 case AMULLW: 855 case AMULLWCC: 856 case ADIVW: 857 case ADIVWCC: 858 case ADIVWU: 859 case ADIVWUCC: 860 case AREM: 861 case AREMCC: 862 case AREMU: 863 case AREMUCC: 864 case ANAND: 865 case ANANDCC: 866 case ANOR: 867 case ANORCC: 868 case ARLWMI: 869 case ARLWMICC: 870 case ARLWNM: 871 case ARLWNMCC: 872 return D_REG; 873 874 case AFADDS: 875 case AFADDSCC: 876 case AFADD: 877 case AFADDCC: 878 case AFSUBS: 879 case AFSUBSCC: 880 case AFSUB: 881 case AFSUBCC: 882 case AFMULS: 883 case AFMULSCC: 884 case AFMUL: 885 case AFMULCC: 886 case AFDIVS: 887 case AFDIVSCC: 888 case AFDIV: 889 case AFDIVCC: 890 case AFNEG: 891 case AFNEGCC: 892 return D_FREG; 893 } 894 return D_NONE; 895 } 896 897 /* 898 * direct reference, 899 * could be set/use depending on 900 * semantics 901 */ 902 int 903 copyas(Adr *a, Adr *v) 904 { 905 906 if(regtyp(v)) 907 if(a->type == v->type) 908 if(a->reg == v->reg) 909 return 1; 910 return 0; 911 } 912 913 /* 914 * either direct or indirect 915 */ 916 int 917 copyau(Adr *a, Adr *v) 918 { 919 920 if(copyas(a, v)) 921 return 1; 922 if(v->type == D_REG) 923 if(a->type == D_OREG) 924 if(v->reg == a->reg) 925 return 1; 926 return 0; 927 } 928 929 int 930 copyau1(Prog *p, Adr *v) 931 { 932 933 if(regtyp(v)) 934 if(p->from.type == v->type || p->to.type == v->type) 935 if(p->reg == v->reg) { 936 if(a2type(p) != v->type) 937 print("botch a2type %P\n", p); 938 return 1; 939 } 940 return 0; 941 } 942 943 /* 944 * substitute s for v in a 945 * return failure to substitute 946 */ 947 int 948 copysub(Adr *a, Adr *v, Adr *s, int f) 949 { 950 951 if(f) 952 if(copyau(a, v)) 953 a->reg = s->reg; 954 return 0; 955 } 956 957 int 958 copysub1(Prog *p1, Adr *v, Adr *s, int f) 959 { 960 961 if(f) 962 if(copyau1(p1, v)) 963 p1->reg = s->reg; 964 return 0; 965 } 966