📄 noop.c
字号:
p = q; break; } if(p->from.type != D_REG){ diag("bad instruction %P", p); break; } o = p->as; q = genIRR(p, ASUBQ, 16LL, NREG, REGSP); q = genstore(q, AMOVQ, p->from.reg, 8LL, REGSP); if (o == ADIVL || o == ADIVL || o == AMODL || o == AMODLU) q->as = AMOVL; q = genRRR(q, AMOVQ, p->reg, NREG, REGTMP); if (p->reg == NREG) q->from.reg = p->to.reg; /* CALL appropriate */ q1 = prg(); q1->link = q->link; q->link = q1; q1->as = AJSR; q1->line = p->line; q1->to.type = D_BRANCH; q1->cond = divsubr(o); q1->mark |= BRANCH; q = q1; q = genRRR(q, AMOVQ, REGTMP, NREG, p->to.reg); q = genIRR(q, AADDQ, 16LL, NREG, REGSP); excise(p); p = q; break; /* Attempt to replace {cond. branch, mov} with a cmov */ /* XXX warning: this is all a bit experimental */ case ABEQ: case ABNE: case ABGE: case ABGT: case ABLE: case ABLT: case ABLBC: case ABLBS: q = p->link; if (q == P) break; q1 = q->link; if (q1 != p->cond || q1 == P) break;/*print("%P\n", q); /* */ if (q->to.type != D_REG) break; if (q->from.type != D_REG && (q->from.type != D_CONST || q->from.name != D_NONE)) break; if (q->mark&LABEL2) break;/* print("%P\n", q); /* */ if (q->as != AMOVQ) /* XXX can handle more than this! */ break; q->as = (p->as^1) + ACMOVEQ-ABEQ; /* sleazy hack */ q->reg = p->from.reg; /* XXX check CMOVx operand order! */ excise(p); /* XXX p's LABEL? */ if (!(q1->mark&LABEL2)) q1->mark &= ~LABEL; break; case AFBEQ: case AFBNE: case AFBGE: case AFBGT: case AFBLE: case AFBLT: q = p->link; if (q == P) break; q1 = q->link; if (q1 != p->cond || q1 == P) break; if (q->from.type != D_FREG || q->to.type != D_FREG) break;/* print("%P\n", q); /* */ if (q->mark&LABEL2) break; if (q->as != AMOVT) /* XXX can handle more than this! */ break; q->as = (p->as^1) + AFCMOVEQ-AFBEQ; /* sleazy hack */ q->reg = p->from.reg; /* XXX check CMOVx operand order! */ excise(p); /* XXX p's LABEL? */ if (!(q1->mark&LABEL2)) q1->mark &= ~LABEL; break; } } curtext = P; q = P; /* p - 1 */ q1 = firstp; /* top of block */ o = 0; /* count of instructions */ for(p = firstp; p != P; p = p1) { p1 = p->link; o++; if(p->mark & NOSCHED){ if(q1 != p){ sched(q1, q); } for(; p != P; p = p->link){ if(!(p->mark & NOSCHED)) break; q = p; } p1 = p; q1 = p; o = 0; continue; } if(p->mark & (LABEL|SYNC)) { if(q1 != p) sched(q1, q); q1 = p; o = 1; } if(p->mark & (BRANCH|SYNC)) { sched(q1, p); q1 = p1; o = 0; } if(o >= NSCHED) { sched(q1, p); q1 = p1; o = 0; } q = p; }}voidnocache(Prog *p){ p->optab = 0; p->from.class = 0; p->to.class = 0;}/* XXX use of this may lose important LABEL flags, check that this isn't happening (or fix) */voidexcise(Prog *p){ Prog *q; q = p->link; *p = *q;}voidinitdiv(void){ Sym *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8; Prog *p; s1 = lookup("_divq", 0); s2 = lookup("_divqu", 0); s3 = lookup("_modq", 0); s4 = lookup("_modqu", 0); s5 = lookup("_divl", 0); s6 = lookup("_divlu", 0); s7 = lookup("_modl", 0); s8 = lookup("_modlu", 0); for(p = firstp; p != P; p = p->link) if(p->as == ATEXT) { if(p->from.sym == s1) prog_divq = p; if(p->from.sym == s2) prog_divqu = p; if(p->from.sym == s3) prog_modq = p; if(p->from.sym == s4) prog_modqu = p; if(p->from.sym == s5) prog_divl = p; if(p->from.sym == s6) prog_divlu = p; if(p->from.sym == s7) prog_modl = p; if(p->from.sym == s8) prog_modlu = p; } if(prog_divq == P) { diag("undefined: %s", s1->name); prog_divq = curtext; } if(prog_divqu == P) { diag("undefined: %s", s2->name); prog_divqu = curtext; } if(prog_modq == P) { diag("undefined: %s", s3->name); prog_modq = curtext; } if(prog_modqu == P) { diag("undefined: %s", s4->name); prog_modqu = curtext; } if(prog_divl == P) { diag("undefined: %s", s5->name); prog_divl = curtext; } if(prog_divlu == P) { diag("undefined: %s", s6->name); prog_divlu = curtext; } if(prog_modl == P) { diag("undefined: %s", s7->name); prog_modl = curtext; } if(prog_modlu == P) { diag("undefined: %s", s8->name); prog_modlu = curtext; }}Prog *divsubr(int o){ switch(o) { case ADIVQ: return prog_divq; case ADIVQU: return prog_divqu; case AMODQ: return prog_modq; case AMODQU: return prog_modqu; case ADIVL: return prog_divl; case ADIVLU: return prog_divlu; case AMODL: return prog_modl; case AMODLU: return prog_modlu; default: diag("bad op %O in divsubr", o); return prog_modlu; }}Prog*divuconst(Prog *p, uvlong y, int num, int quot, int bits){ int logy, i, shift; uvlong k, m, n, mult, tmp, msb; if(num == NREG) num = quot; if(y == 0) { diag("division by zero"); return p; } if(y == 1) return genRRR(p, AMOVQ, num, NREG, quot); if(num == REGTMP || quot == REGTMP) diag("bad register in divuconst"); tmp = y; for(logy = -1; tmp != 0; logy++) tmp >>= 1; msb = (1LL << (bits-1)); if((y & (y-1)) == 0) /* power of 2 */ return genIRR(p, ASRLQ, logy, num, quot); if(y > msb) return genIRR(p, ACMPUGE, y, num, quot); /* k = (-2^(bits+logy)) % y */ m = msb/y; n = msb%y; if(debug['d']) Bprint(&bso, "divuconst: y=%lld msb=%lld m=%lld n=%lld\n", y, msb, m, n); for(i = 0; i <= logy; i++) { m *= 2LL; n *= 2LL; if(n > y) { m += 1LL; n -= y; } } if(debug['d']) Bprint(&bso, "divuconst: y=%lld msb=%lld m=%lld n=%lld\n", y, msb, m, n); k = y - n; if(k > (1LL << logy)) { mult = 2LL*m + 1LL; bits++; } else mult = m + 1LL; shift = bits + logy; if(debug['d']) Bprint(&bso, "divuconst: y=%lld mult=%lld shift=%d bits=%d k=%lld\n", y, mult, shift, bits, k); if(bits <= 32) { p = genIRR(p, AMOVQ, mult, NREG, REGTMP); p = genRRR(p, AEXTLL, REGZERO, num, quot); p = genRRR(p, AMULQ, REGTMP, quot, quot); p = genIRR(p, ASRLQ, shift, quot, quot); p = genRRR(p, AADDL, quot, REGZERO, quot); return p; } if(bits == 33) { if(shift < 64) { mult <<= (64-shift); shift = 64; } p = genIRR(p, AMOVQ, mult, NREG, REGTMP); p = genRRR(p, AEXTLL, REGZERO, num, quot); p = genRRR(p, AUMULH, REGTMP, quot, quot); if(shift != 64) p = genIRR(p, ASRLQ, shift-64, quot, quot); p = genRRR(p, AADDL, quot, REGZERO, quot); return p; } if(bits <= 64) { if(shift < 64) { mult <<= (64-shift); shift = 64; } p = genIRR(p, AMOVQ, mult, NREG, REGTMP); p = genRRR(p, AUMULH, REGTMP, num, quot); if(shift != 64) p = genIRR(p, ASRLQ, shift-64, quot, quot); return p; } p = genIRR(p, AMOVQ, mult, NREG, REGTMP); p = genRRR(p, AUMULH, REGTMP, num, REGTMP); p = genRRR(p, AADDQ, num, REGTMP, quot); p = genRRR(p, ACMPUGT, REGTMP, quot, REGTMP); p = genIRR(p, ASLLQ, 128-shift, REGTMP, REGTMP); p = genIRR(p, ASRLQ, shift-64, quot, quot); p = genRRR(p, AADDQ, REGTMP, quot, quot); return p;}Prog *divconst(Prog *p, vlong y, int num, int quot, int bits){ vlong yabs; Prog *q; yabs = y; if (y < 0) yabs = -y; q = genRRR(p, ASUBQ, num, REGZERO, REGTMP2); if (num != quot) q = genRRR(q, AMOVQ, num, NREG, quot); q = genRRR(q, ACMOVGT, REGTMP2, REGTMP2, quot); q = divuconst(q, yabs, quot, quot, bits-1); q = genRRR(q, ASUBQ, quot, REGZERO, REGTMP); q = genRRR(q, (y < 0)? ACMOVLT: ACMOVGT, REGTMP, REGTMP2, quot); return q;}Prog *modconst(Prog *p, vlong y, int num, int quot, int bits){ vlong yabs; Prog *q; yabs = y; if (y < 0) yabs = -y; q = genRRR(p, ASUBQ, num, REGZERO, REGTMP2); q = genRRR(q, ACMOVLT, num, REGTMP2, REGTMP2); q = divuconst(q, yabs, REGTMP2, REGTMP2, bits-1); q = genRRR(q, ASUBQ, REGTMP2, REGZERO, REGTMP); q = genRRR(q, ACMOVLT, REGTMP, num, REGTMP2); q = genIRR(q, AMULQ, yabs, REGTMP2, REGTMP2); q = genRRR(q, ASUBQ, REGTMP2, num, quot); return q;}Prog *genXXX(Prog *q, int op, Adr *from, int reg, Adr *to){ Prog *p; p = prg(); p->as = op; p->line = q->line; p->from = *from; p->to = *to; p->reg = reg; p->link = q->link; q->link = p; return p;}Prog *genRRR(Prog *q, int op, int from, int reg, int to){ Prog *p; p = prg(); p->as = op; p->line = q->line; p->from.type = D_REG; p->from.reg = from; p->to.type = D_REG; p->to.reg = to; p->reg = reg; p->link = q->link; q->link = p; return p;}Prog *genIRR(Prog *q, int op, vlong v, int reg, int to){ Prog *p; p = prg(); p->as = op; p->line = q->line; p->from.type = D_CONST; p->from.offset = v; p->to.type = D_REG; p->to.reg = to; p->reg = reg; p->link = q->link; q->link = p; return p;}Prog *genstore(Prog *q, int op, int from, vlong offset, int to){ Prog *p; p = prg(); p->as = op; p->line = q->line; p->from.type = D_REG; p->from.reg = from; p->to.type = D_OREG; p->to.reg = to; p->to.offset = offset; p->reg = NREG; p->link = q->link; q->link = p; return p;}Prog *genload(Prog *q, int op, vlong offset, int from, int to){ Prog *p; p = prg(); p->as = op; p->line = q->line; p->from.type = D_OREG; p->from.offset = offset; p->from.reg = from; p->to.type = D_REG; p->to.reg = to; p->reg = NREG; p->link = q->link; q->link = p; return p;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -