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