static void xfol(Prog *p, Prog **last) { Prog *q; int i; enum as a; loop: if(p == P) return; if(p->as == AJMP) if((q = p->pcond) != P && q->as != ATEXT) { /* mark instruction as done and continue layout at target of jump */ p->mark = 1; p = q; if(p->mark == 0) goto loop; } if(p->mark) { /* * p goes here, but already used it elsewhere. * copy up to 4 instructions or else branch to other copy. */ for(i=0,q=p; i<4; i++,q=q->link) { if(q == P) break; if(q == *last) break; a = q->as; if(a == ANOP) { i--; continue; } if(nofollow(a) || pushpop(a)) break; // NOTE(rsc): arm does goto copy if(q->pcond == P || q->pcond->mark) continue; if(a == ACALL || a == ALOOP) continue; for(;;) { if(p->as == ANOP) { p = p->link; continue; } q = copyp(p); p = p->link; q->mark = 1; (*last)->link = q; *last = q; if(q->as != a || q->pcond == P || q->pcond->mark) continue; q->as = relinv(q->as); p = q->pcond; q->pcond = q->link; q->link = p; xfol(q->link, last); p = q->link; if(p->mark) return; goto loop; } } /* */ q = prg(); q->as = AJMP; q->line = p->line; q->to.type = D_BRANCH; q->to.offset = p->pc; q->pcond = p; p = q; } /* emit p */ p->mark = 1; (*last)->link = p; *last = p; a = p->as; /* continue loop with what comes after p */ if(nofollow(a)) return; if(p->pcond != P && a != ACALL) { /* * some kind of conditional branch. * recurse to follow one path. * continue loop on the other. */ q = brchain(p->link); if(q != P && q->mark) if(a != ALOOP) { p->as = relinv(a); p->link = p->pcond; p->pcond = q; } xfol(p->link, last); q = brchain(p->pcond); if(q->mark) { p->pcond = q; return; } p = q; goto loop; } p = p->link; goto loop; }
void xfol(Prog *p) { Prog *q; int i; enum as a; loop: if(p == P) return; if(p->as == ATEXT) curtext = p; if(p->as == AJMP) if((q = p->pcond) != P) { p->mark = 1; p = q; if(p->mark == 0) goto loop; } if(p->mark) { /* copy up to 4 instructions to avoid branch */ for(i=0,q=p; i<4; i++,q=q->link) { if(q == P) break; if(q == lastp) break; a = q->as; if(a == ANOP) { i--; continue; } switch(a) { case AJMP: case ARET: case AIRETL: case APUSHL: case APUSHFL: case APUSHW: case APUSHFW: case APOPL: case APOPFL: case APOPW: case APOPFW: goto brk; } if(q->pcond == P || q->pcond->mark) continue; if(a == ACALL || a == ALOOP) continue; for(;;) { if(p->as == ANOP) { p = p->link; continue; } q = copyp(p); p = p->link; q->mark = 1; lastp->link = q; lastp = q; if(q->as != a || q->pcond == P || q->pcond->mark) continue; q->as = relinv(q->as); p = q->pcond; q->pcond = q->link; q->link = p; xfol(q->link); p = q->link; if(p->mark) return; goto loop; } } /* */ brk: ; q = prg(); q->as = AJMP; q->line = p->line; q->to.type = D_BRANCH; q->to.offset = p->pc; q->pcond = p; p = q; } p->mark = 1; lastp->link = p; lastp = p; a = p->as; if(a == AJMP || a == ARET || a == AIRETL) return; if(p->pcond != P) if(a != ACALL) { q = brchain(p->link); if(q != P && q->mark) if(a != ALOOP) { p->as = relinv(a); p->link = p->pcond; p->pcond = q; } xfol(p->link); q = brchain(p->pcond); if(q->mark) { p->pcond = q; return; } p = q; goto loop; } p = p->link; goto loop; }
void xfol(Prog *p) { Prog *q, *r; int a, i; loop: if(p == P) return; setarch(p); a = p->as; if(a == ATEXT) curtext = p; if(!curtext->from.sym->reachable) { p = p->cond; goto loop; } if(a == AB) { q = p->cond; if(q != P) { p->mark |= FOLL; p = q; if(!(p->mark & FOLL)) goto loop; } } if(p->mark & FOLL) { for(i=0,q=p; i<4; i++,q=q->link) { if(q == lastp) break; a = q->as; if(a == ANOP) { i--; continue; } if(a == AB || (a == ARET && q->scond == 14) || a == ARFE) goto copy; if(!q->cond || (q->cond->mark&FOLL)) continue; if(a != ABEQ && a != ABNE) continue; copy: for(;;) { r = prg(); *r = *p; if(!(r->mark&FOLL)) print("cant happen 1\n"); r->mark |= FOLL; if(p != q) { p = p->link; lastp->link = r; lastp = r; continue; } lastp->link = r; lastp = r; if(a == AB || (a == ARET && q->scond == 14) || a == ARFE) return; r->as = ABNE; if(a == ABNE) r->as = ABEQ; r->cond = p->link; r->link = p->cond; if(!(r->link->mark&FOLL)) xfol(r->link); if(!(r->cond->mark&FOLL)) print("cant happen 2\n"); return; } } a = AB; q = prg(); q->as = a; q->line = p->line; q->to.type = D_BRANCH; q->to.offset = p->pc; q->cond = p; p = q; } p->mark |= FOLL; lastp->link = p; lastp = p; if(a == AB || (a == ARET && p->scond == 14) || a == ARFE){ return; } if(p->cond != P) if(a != ABL && a != ABX && p->link != P) { q = brchain(p->link); if(a != ATEXT && a != ABCASE) if(q != P && (q->mark&FOLL)) { p->as = relinv(a); p->link = p->cond; p->cond = q; } xfol(p->link); q = brchain(p->cond); if(q == P) q = p->cond; if(q->mark&FOLL) { p->cond = q; return; } p = q; goto loop; } p = p->link; goto loop; }
static void xfol(Prog *p, Prog **last) { Prog *q, *r; int a, i; loop: if(p == P) return; a = p->as; if(a == AB) { q = p->cond; if(q != P && q->as != ATEXT) { p->mark |= FOLL; p = q; if(!(p->mark & FOLL)) goto loop; } } if(p->mark & FOLL) { for(i=0,q=p; i<4; i++,q=q->link) { if(q == *last || q == nil) break; a = q->as; if(a == ANOP) { i--; continue; } if(a == AB || (a == ARET && q->scond == 14) || a == ARFE || a == AUNDEF) goto copy; if(q->cond == P || (q->cond->mark&FOLL)) continue; if(a != ABEQ && a != ABNE) continue; copy: for(;;) { r = prg(); *r = *p; if(!(r->mark&FOLL)) print("can't happen 1\n"); r->mark |= FOLL; if(p != q) { p = p->link; (*last)->link = r; *last = r; continue; } (*last)->link = r; *last = r; if(a == AB || (a == ARET && q->scond == 14) || a == ARFE || a == AUNDEF) return; r->as = ABNE; if(a == ABNE) r->as = ABEQ; r->cond = p->link; r->link = p->cond; if(!(r->link->mark&FOLL)) xfol(r->link, last); if(!(r->cond->mark&FOLL)) print("can't happen 2\n"); return; } } a = AB; q = prg(); q->as = a; q->line = p->line; q->to.type = D_BRANCH; q->to.offset = p->pc; q->cond = p; p = q; } p->mark |= FOLL; (*last)->link = p; *last = p; if(a == AB || (a == ARET && p->scond == 14) || a == ARFE || a == AUNDEF){ return; } if(p->cond != P) if(a != ABL && a != ABX && p->link != P) { q = brchain(p->link); if(a != ATEXT && a != ABCASE) if(q != P && (q->mark&FOLL)) { p->as = relinv(a); p->link = p->cond; p->cond = q; } xfol(p->link, last); q = brchain(p->cond); if(q == P) q = p->cond; if(q->mark&FOLL) { p->cond = q; return; } p = q; goto loop; } p = p->link; goto loop; }