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 } 967