📄 noop.c
字号:
#include "l.h"Prog *divuconst(Prog *, uvlong, int, int, int);Prog *divconst(Prog *, vlong, int, int, int);Prog *modconst(Prog *, vlong, int, int, int);void excise(Prog *);voidnoops(void){ Prog *p, *p1, *q, *q1, *q2; int o, curframe, curbecome, maxbecome, shift; /* * find leaf subroutines * become sizes * frame sizes * strip NOPs * expand RET and other macros * expand BECOME pseudo * use conditional moves where appropriate */ if(debug['v']) Bprint(&bso, "%5.2f noops\n", cputime()); Bflush(&bso); curframe = 0; curbecome = 0; maxbecome = 0; curtext = 0; q = P; for(p = firstp; p != P; p = p->link) { /* find out how much arg space is used in this TEXT */ if(p->to.type == D_OREG && p->to.reg == REGSP) if(p->to.offset > curframe) curframe = p->to.offset; switch(p->as) { case ATEXT: if(curtext && curtext->from.sym) { curtext->from.sym->frame = curframe; curtext->from.sym->become = curbecome; if(curbecome > maxbecome) maxbecome = curbecome; } curframe = 0; curbecome = 0; p->mark |= LABEL|LEAF|SYNC; if(p->link) p->link->mark |= LABEL; curtext = p; break; /* don't mess with what we don't understand */ case AWORD: case ACALL_PAL: /* etc. */ p->mark |= LABEL; for(q1=p->link; q1 != P; q1 = q1->link) { q1->mark |= LABEL; if(q1->as != AXORNOT) /* used as NOP in PALcode */ break; } break; case ARET: /* special form of RET is BECOME */ if(p->from.type == D_CONST) if(p->from.offset > curbecome) curbecome = p->from.offset; if(p->link != P) p->link->mark |= LABEL; break; case ANOP: q1 = p->link; q->link = q1; /* q is non-nop */ q1->mark |= p->mark; continue; case AJSR: if(curtext != P) curtext->mark &= ~LEAF; case ABEQ: case ABNE: case ABGE: case ABGT: case ABLE: case ABLT: case ABLBC: case ABLBS: case AFBEQ: case AFBNE: case AFBGE: case AFBGT: case AFBLE: case AFBLT: case AJMP: p->mark |= BRANCH; q1 = p->cond; if(q1 != P) { while(q1->as == ANOP) { q1 = q1->link; p->cond = q1; } if(!(q1->mark & LEAF)) { if (q1->mark & LABEL) q1->mark |= LABEL2; else q1->mark |= LABEL; } } else p->mark |= LABEL; q1 = p->link; if(q1 != P) { if (q1->mark & LABEL) q1->mark |= LABEL2; else q1->mark |= LABEL; } else p->mark |= LABEL; /* ??? */ break; case ADIVQ: case ADIVQU: case AMODQ: case AMODQU: case ADIVL: case ADIVLU: case AMODL: case AMODLU: if(p->from.type == D_CONST /*&& !debug['d']*/) continue; if(prog_divq == P) initdiv(); if(curtext != P) curtext->mark &= ~LEAF; break; } q = p; } if(curtext && curtext->from.sym) { curtext->from.sym->frame = curframe; curtext->from.sym->become = curbecome; if(curbecome > maxbecome) maxbecome = curbecome; } if(debug['b']) print("max become = %d\n", maxbecome); xdefine("ALEFbecome", STEXT, maxbecome); curtext = 0; for(p = firstp; p != P; p = p->link) { switch(p->as) { case ATEXT: curtext = p; break; case AJSR: if(curtext != P && curtext->from.sym != S && curtext->to.offset >= 0) { o = maxbecome - curtext->from.sym->frame; if(o <= 0) break; /* calling a become or calling a variable */ if(p->to.sym == S || p->to.sym->become) { curtext->to.offset += o; if(debug['b']) { curp = p; print("%D calling %D increase %d\n", &curtext->from, &p->to, o); } } } break; } } for(p = firstp; p != P; p = p->link) { o = p->as; switch(o) { case ATEXT: curtext = p; autosize = p->to.offset + 8; if(autosize <= 8) if(curtext->mark & LEAF) { p->to.offset = -8; autosize = 0; } if (autosize & 4) autosize += 4; q = p; if(autosize) q = genIRR(p, ASUBQ, autosize, NREG, REGSP); else if(!(curtext->mark & LEAF)) { if(debug['v']) Bprint(&bso, "save suppressed in: %s\n", curtext->from.sym->name); Bflush(&bso); curtext->mark |= LEAF; } if(curtext->mark & LEAF) { if(curtext->from.sym) curtext->from.sym->type = SLEAF; break; } genstore(q, AMOVL, REGLINK, 0LL, REGSP); break; case ARET: nocache(p); if(p->from.type == D_CONST) goto become; if(curtext->mark & LEAF) { if(!autosize) { p->as = AJMP; p->from = zprg.from; p->to.type = D_OREG; p->to.offset = 0; p->to.reg = REGLINK; break; } p->as = AADDQ; p->from.type = D_CONST; p->from.offset = autosize; p->to.type = D_REG; p->to.reg = REGSP; q = prg(); q->as = AJMP; q->line = p->line; q->to.type = D_OREG; q->to.offset = 0; q->to.reg = REGLINK; q->mark |= BRANCH; q->link = p->link; p->link = q; break; } p->as = AMOVL; p->from.type = D_OREG; p->from.offset = 0; p->from.reg = REGSP; p->to.type = D_REG; p->to.reg = REGLINK; q = p; if(autosize) q = genIRR(p, AADDQ, autosize, NREG, REGSP); q1 = prg(); q1->as = AJMP; q1->line = p->line; q1->to.type = D_OREG; q1->to.offset = 0; q1->to.reg = REGLINK; q1->mark |= BRANCH; q1->link = q->link; q->link = q1; break; become: if(curtext->mark & LEAF) { q = prg(); q->line = p->line; q->as = AJMP; q->from = zprg.from; q->to = p->to; q->cond = p->cond; q->link = p->link; q->mark |= BRANCH; p->link = q; p->as = AADDQ; p->from = zprg.from; p->from.type = D_CONST; p->from.offset = autosize; p->to = zprg.to; p->to.type = D_REG; p->to.reg = REGSP; break; } q = prg(); q->line = p->line; q->as = AJMP; q->from = zprg.from; q->to = p->to; q->cond = p->cond; q->link = p->link; q->mark |= BRANCH; p->link = q; q = genIRR(p, AADDQ, autosize, NREG, REGSP); p->as = AMOVL; p->from = zprg.from; p->from.type = D_OREG; p->from.offset = 0; p->from.reg = REGSP; p->to = zprg.to; p->to.type = D_REG; p->to.reg = REGLINK; break; /* All I wanted was a MOVB... */ case AMOVB: case AMOVW: /* rewrite sign extend; could use v3 extension in asmout case 1 */ if (p->to.type == D_REG) { nocache(p); shift = (p->as == AMOVB) ? (64-8) : (64-16); if (p->from.type == D_REG) { p->as = ASLLQ; p->reg = p->from.reg; p->from.type = D_CONST; p->from.offset = shift; q = genIRR(p, ASRAQ, shift, p->to.reg, p->to.reg); break; } else { p->as = (p->as == AMOVB) ? AMOVBU : AMOVWU; q = genIRR(p, ASLLQ, shift, p->to.reg, p->to.reg); q = genIRR(q, ASRAQ, shift, p->to.reg, p->to.reg); } } /* fall through... */ case AMOVBU: case AMOVWU: if(!debug['x']) break; /* use BWX extension */ o = p->as; nocache(p); if (p->from.type == D_OREG) { if (p->to.type != D_REG) break; p->as = AMOVQU; q = genXXX(p, AEXTBL, &p->to, REGTMP2, &p->to); if (o == AMOVW || o == AMOVWU) q->as = AEXTWL; p->to.reg = REGTMP2; if ((p->from.offset & 7) != 0 || aclass(&p->from) != C_SOREG) { q1 = genXXX(p, AMOVA, &p->from, NREG, &q->to); q1->from.offset &= 7; q->from = q->to; } else q->from.reg = p->from.reg; if (o == AMOVB || o == AMOVW) genXXX(q, o, &q->to, NREG, &q->to); } else if (p->to.type == D_OREG) { if (aclass(&p->from) == C_ZCON) { p->from.type = D_REG; p->from.reg = REGZERO; } else if (p->from.type != D_REG) break; p->as = AMOVQU; q = genRRR(p, AMSKBL, p->to.reg, REGTMP2, REGTMP2); q1 = genRRR(q, AINSBL, p->to.reg, p->from.reg, REGTMP); if (o == AMOVW || o == AMOVWU) { q->as = AMSKWL; q1->as = AINSWL; } q2 = genXXX(q1, AOR, &q->to, REGTMP, &q->to); genXXX(q2, AMOVQU, &q->to, NREG, &p->to); p->from = p->to; p->to = q->to; if ((p->from.offset & 7) != 0 || aclass(&p->from) != C_SOREG) { q->from.reg = REGTMP; q1->from.reg = REGTMP; q = genXXX(p, AMOVA, &p->from, NREG, &q->from); q->from.offset &= 7; } } break; case ASLLL: p->as = ASLLQ; p = genXXX(p, AADDL, &p->to, REGZERO, &p->to); break; case ASRLL: if (p->to.type != D_REG) { diag("illegal dest type in %P", p); break; } if (p->reg == NREG) p->reg = p->to.reg; q = genXXX(p, ASRLQ, &p->from, REGTMP, &p->to); p->as = AZAP; p->from.type = D_CONST; p->from.offset = 0xf0; p->to.reg = REGTMP; p = q; p = genXXX(p, AADDL, &p->to, REGZERO, &p->to); break; case ASRAL: p->as = ASRAQ; break; case ADIVQ: case ADIVQU: case AMODQ: case AMODQU: case ADIVL: case ADIVLU: case AMODL: case AMODLU: /* if (debug['d']) print("%P\n", p); */ if(p->to.type != D_REG) break; /*if(debug['d'] && p->from.type == D_CONST) { q = genRRR(p, p->as, REGTMP, p->reg, p->to.reg); p->as = AMOVQ; p->reg = NREG; p->to.reg = REGTMP; p = q; }*/ if(p->from.type == D_CONST) { if (p->reg == NREG) p->reg = p->to.reg; switch (p->as) { case ADIVQ: q = divconst(p, p->from.offset, p->reg, p->to.reg, 64); break; case ADIVQU: q = divuconst(p, p->from.offset, p->reg, p->to.reg, 64); break; case AMODQ: q = modconst(p, p->from.offset, p->reg, p->to.reg, 64); break; case AMODQU: q = divuconst(p, p->from.offset, p->reg, REGTMP2, 64); q = genIRR(q, AMULQ, p->from.offset, REGTMP2, REGTMP2); q = genRRR(q, ASUBQ, REGTMP2, p->reg, p->to.reg); break; case ADIVL: q = divconst(p, p->from.offset, p->reg, p->to.reg, 32); break; case ADIVLU: q = divuconst(p, p->from.offset, p->reg, p->to.reg, 32); break; case AMODL: q = modconst(p, p->from.offset, p->reg, p->to.reg, 32); break; case AMODLU: q = divuconst(p, p->from.offset, p->reg, REGTMP2, 32); q = genIRR(q, AMULQ, p->from.offset, REGTMP2, REGTMP2); q = genRRR(q, ASUBQ, REGTMP2, p->reg, p->to.reg); break; } excise(p);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -