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 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 int 530 copy1(Adr *v1, Adr *v2, Reg *r, int f) 531 { 532 int t; 533 Prog *p; 534 535 if(r->active) { 536 if(debug['P']) 537 print("act set; return 1\n"); 538 return 1; 539 } 540 r->active = 1; 541 if(debug['P']) 542 print("copy %D->%D f=%d\n", v1, v2, f); 543 for(; r != R; r = r->s1) { 544 p = r->prog; 545 if(debug['P']) 546 print("%P", p); 547 if(!f && uniqp(r) == R) { 548 f = 1; 549 if(debug['P']) 550 print("; merge; f=%d", f); 551 } 552 t = copyu(p, v2, A); 553 switch(t) { 554 case 2: /* rar, cant split */ 555 if(debug['P']) 556 print("; %Drar; return 0\n", v2); 557 return 0; 558 559 case 3: /* set */ 560 if(debug['P']) 561 print("; %Dset; return 1\n", v2); 562 return 1; 563 564 case 1: /* used, substitute */ 565 case 4: /* use and set */ 566 if(f) { 567 if(!debug['P']) 568 return 0; 569 if(t == 4) 570 print("; %Dused+set and f=%d; return 0\n", v2, f); 571 else 572 print("; %Dused and f=%d; return 0\n", v2, f); 573 return 0; 574 } 575 if(copyu(p, v2, v1)) { 576 if(debug['P']) 577 print("; sub fail; return 0\n"); 578 return 0; 579 } 580 if(debug['P']) 581 print("; sub%D/%D", v2, v1); 582 if(t == 4) { 583 if(debug['P']) 584 print("; %Dused+set; return 1\n", v2); 585 return 1; 586 } 587 break; 588 } 589 if(!f) { 590 t = copyu(p, v1, A); 591 if(!f && (t == 2 || t == 3 || t == 4)) { 592 f = 1; 593 if(debug['P']) 594 print("; %Dset and !f; f=%d", v1, f); 595 } 596 } 597 if(debug['P']) 598 print("\n"); 599 if(r->s2) 600 if(!copy1(v1, v2, r->s2, f)) 601 return 0; 602 } 603 return 1; 604 } 605 606 /* 607 * return 608 * 1 if v only used (and substitute), 609 * 2 if read-alter-rewrite 610 * 3 if set 611 * 4 if set and used 612 * 0 otherwise (not touched) 613 */ 614 int 615 copyu(Prog *p, Adr *v, Adr *s) 616 { 617 618 switch(p->as) { 619 620 default: 621 if(debug['P']) 622 print(" (?)"); 623 return 2; 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 ARLWMI: /* read read rar */ 670 case ARLWMICC: 671 if(copyas(&p->to, v)) 672 return 2; 673 /* fall through */ 674 675 case AADD: /* read read write */ 676 case AADDC: 677 case AADDE: 678 case ASUB: 679 case ASLW: 680 case ASRW: 681 case ASRAW: 682 case AOR: 683 case AORCC: 684 case AORN: 685 case AORNCC: 686 case AAND: 687 case AANDCC: 688 case AANDN: 689 case AANDNCC: 690 case ANAND: 691 case ANANDCC: 692 case ANOR: 693 case ANORCC: 694 case AXOR: 695 case AMULHW: 696 case AMULHWU: 697 case AMULLW: 698 case ADIVW: 699 case ADIVWU: 700 case AREM: 701 case AREMU: 702 case ARLWNM: 703 case ARLWNMCC: 704 705 case AFADDS: 706 case AFADD: 707 case AFSUBS: 708 case AFSUB: 709 case AFMULS: 710 case AFMUL: 711 case AFDIVS: 712 case AFDIV: 713 if(s != A) { 714 if(copysub(&p->from, v, s, 1)) 715 return 1; 716 if(copysub1(p, v, s, 1)) 717 return 1; 718 if(!copyas(&p->to, v)) 719 if(copysub(&p->to, v, s, 1)) 720 return 1; 721 return 0; 722 } 723 if(copyas(&p->to, v)) { 724 if(p->reg == NREG) 725 p->reg = p->to.reg; 726 if(copyau(&p->from, v)) 727 return 4; 728 if(copyau1(p, v)) 729 return 4; 730 return 3; 731 } 732 if(copyau(&p->from, v)) 733 return 1; 734 if(copyau1(p, v)) 735 return 1; 736 if(copyau(&p->to, v)) 737 return 1; 738 return 0; 739 740 case ABEQ: 741 case ABGT: 742 case ABGE: 743 case ABLT: 744 case ABLE: 745 case ABNE: 746 case ABVC: 747 case ABVS: 748 break; 749 750 case ACMP: /* read read */ 751 case ACMPU: 752 case AFCMPO: 753 case AFCMPU: 754 if(s != A) { 755 if(copysub(&p->from, v, s, 1)) 756 return 1; 757 return copysub(&p->to, v, s, 1); 758 } 759 if(copyau(&p->from, v)) 760 return 1; 761 if(copyau(&p->to, v)) 762 return 1; 763 break; 764 765 case ABR: /* funny */ 766 if(s != A) { 767 if(copysub(&p->to, v, s, 1)) 768 return 1; 769 return 0; 770 } 771 if(copyau(&p->to, v)) 772 return 1; 773 return 0; 774 775 case ARETURN: /* funny */ 776 if(v->type == D_REG) 777 if(v->reg == REGRET) 778 return 2; 779 if(v->type == D_FREG) 780 if(v->reg == FREGRET) 781 return 2; 782 783 case ABL: /* funny */ 784 if(v->type == D_REG) { 785 if(v->reg <= REGEXT && v->reg > exregoffset) 786 return 2; 787 if(v->reg == REGARG) 788 return 2; 789 } 790 if(v->type == D_FREG) { 791 if(v->reg <= FREGEXT && v->reg > exfregoffset) 792 return 2; 793 } 794 795 if(s != A) { 796 if(copysub(&p->to, v, s, 1)) 797 return 1; 798 return 0; 799 } 800 if(copyau(&p->to, v)) 801 return 4; 802 return 3; 803 804 case ATEXT: /* funny */ 805 if(v->type == D_REG) 806 if(v->reg == REGARG) 807 return 3; 808 return 0; 809 } 810 return 0; 811 } 812 813 int 814 a2type(Prog *p) 815 { 816 817 switch(p->as) { 818 case AADD: 819 case AADDC: 820 case AADDCC: 821 case AADDCCC: 822 case AADDE: 823 case AADDECC: 824 case AADDME: 825 case AADDMECC: 826 case AADDZE: 827 case AADDZECC: 828 case ASUB: 829 case ASUBC: 830 case ASUBCC: 831 case ASUBCCC: 832 case ASUBE: 833 case ASUBECC: 834 case ASUBME: 835 case ASUBMECC: 836 case ASUBZE: 837 case ASUBZECC: 838 case ASLW: 839 case ASLWCC: 840 case ASRW: 841 case ASRWCC: 842 case ASRAW: 843 case ASRAWCC: 844 case AOR: 845 case AORCC: 846 case AORN: 847 case AORNCC: 848 case AAND: 849 case AANDCC: 850 case AANDN: 851 case AANDNCC: 852 case AXOR: 853 case AXORCC: 854 case ANEG: 855 case ANEGCC: 856 case AMULHW: 857 case AMULHWU: 858 case AMULLW: 859 case AMULLWCC: 860 case ADIVW: 861 case ADIVWCC: 862 case ADIVWU: 863 case ADIVWUCC: 864 case AREM: 865 case AREMCC: 866 case AREMU: 867 case AREMUCC: 868 case ANAND: 869 case ANANDCC: 870 case ANOR: 871 case ANORCC: 872 case ARLWMI: 873 case ARLWMICC: 874 case ARLWNM: 875 case ARLWNMCC: 876 return D_REG; 877 878 case AFADDS: 879 case AFADDSCC: 880 case AFADD: 881 case AFADDCC: 882 case AFSUBS: 883 case AFSUBSCC: 884 case AFSUB: 885 case AFSUBCC: 886 case AFMULS: 887 case AFMULSCC: 888 case AFMUL: 889 case AFMULCC: 890 case AFDIVS: 891 case AFDIVSCC: 892 case AFDIV: 893 case AFDIVCC: 894 case AFNEG: 895 case AFNEGCC: 896 return D_FREG; 897 } 898 return D_NONE; 899 } 900 901 /* 902 * direct reference, 903 * could be set/use depending on 904 * semantics 905 */ 906 int 907 copyas(Adr *a, Adr *v) 908 { 909 910 if(regtyp(v)) 911 if(a->type == v->type) 912 if(a->reg == v->reg) 913 return 1; 914 return 0; 915 } 916 917 /* 918 * either direct or indirect 919 */ 920 int 921 copyau(Adr *a, Adr *v) 922 { 923 924 if(copyas(a, v)) 925 return 1; 926 if(v->type == D_REG) 927 if(a->type == D_OREG) 928 if(v->reg == a->reg) 929 return 1; 930 return 0; 931 } 932 933 int 934 copyau1(Prog *p, Adr *v) 935 { 936 937 if(regtyp(v)) 938 if(p->from.type == v->type || p->to.type == v->type) 939 if(p->reg == v->reg) { 940 if(a2type(p) != v->type) 941 print("botch a2type %P\n", p); 942 return 1; 943 } 944 return 0; 945 } 946 947 /* 948 * substitute s for v in a 949 * return failure to substitute 950 */ 951 int 952 copysub(Adr *a, Adr *v, Adr *s, int f) 953 { 954 955 if(f) 956 if(copyau(a, v)) 957 a->reg = s->reg; 958 return 0; 959 } 960 961 int 962 copysub1(Prog *p1, Adr *v, Adr *s, int f) 963 { 964 965 if(f) 966 if(copyau1(p1, v)) 967 p1->reg = s->reg; 968 return 0; 969 } 970