📄 txt.c
字号:
if(t->op == ONAME || t->op == OINDREG || t->op == OIND) { switch(tt) { default: a = AMOVW; break; case TUCHAR: a = AMOVBZ; break; case TCHAR: a = AMOVB; break; case TUSHORT: a = AMOVHZ; break; case TSHORT: a = AMOVH; break; case TFLOAT: a = AFMOVS; break; case TVLONG: case TDOUBLE: a = AFMOVD; break; } if(R0ISZERO && !typefd[ft] && vconst(f) == 0) { gins(a, f, t); return; } if(ft == tt) regalloc(&nod, t, f); else regalloc(&nod, t, Z); gmove(f, &nod); gins(a, &nod, t); regfree(&nod); return; } /* * type x type cross table */ a = AGOK; switch(ft) { case TDOUBLE: case TVLONG: case TFLOAT: switch(tt) { case TDOUBLE: case TVLONG: a = AFMOVD; if(ft == TFLOAT) a = AFMOVS; /* AFMOVSD */ break; case TFLOAT: a = AFRSP; if(ft == TFLOAT) a = AFMOVS; break; case TINT: case TUINT: case TLONG: case TULONG: case TIND: case TSHORT: case TUSHORT: case TCHAR: case TUCHAR: /* BUG: not right for unsigned long */ regalloc(&nod, f, Z); /* should be type float */ regsalloc(&fxrat, f); gins(AFCTIWZ, f, &nod); gins(AFMOVD, &nod, &fxrat); regfree(&nod); fxrat.type = nodrat->type; fxrat.etype = nodrat->etype; fxrat.xoffset += 4; gins(AMOVW, &fxrat, t); gmove(t, t); return; } break; case TINT: case TUINT: case TLONG: case TULONG: case TIND: switch(tt) { case TDOUBLE: case TVLONG: case TFLOAT: goto fxtofl; case TINT: case TUINT: case TLONG: case TULONG: case TIND: case TSHORT: case TUSHORT: case TCHAR: case TUCHAR: a = AMOVW; break; } break; case TSHORT: switch(tt) { case TDOUBLE: case TVLONG: case TFLOAT: goto fxtofl; case TINT: case TUINT: case TLONG: case TULONG: case TIND: a = AMOVH; break; case TSHORT: case TUSHORT: case TCHAR: case TUCHAR: a = AMOVW; break; } break; case TUSHORT: switch(tt) { case TDOUBLE: case TVLONG: case TFLOAT: goto fxtofl; case TINT: case TUINT: case TLONG: case TULONG: case TIND: a = AMOVHZ; break; case TSHORT: case TUSHORT: case TCHAR: case TUCHAR: a = AMOVW; break; } break; case TCHAR: switch(tt) { case TDOUBLE: case TVLONG: case TFLOAT: goto fxtofl; case TINT: case TUINT: case TLONG: case TULONG: case TIND: case TSHORT: case TUSHORT: a = AMOVB; break; case TCHAR: case TUCHAR: a = AMOVW; break; } break; case TUCHAR: switch(tt) { case TDOUBLE: case TVLONG: case TFLOAT: fxtofl: /* * rat[0] = 0x43300000; rat[1] = f^0x80000000; * t = *(double*)rat - FREGCVI; * is-unsigned(t) => if(t<0) t += 2^32; * could be streamlined for int-to-float */ regalloc(&fxc0, f, Z); regalloc(&fxc2, f, Z); regsalloc(&fxrat, t); /* should be type float */ gins(AMOVW, nodconst(0x43300000L), &fxc0); gins(AMOVW, f, &fxc2); gins(AMOVW, &fxc0, &fxrat); gins(AXOR, nodconst(0x80000000L), &fxc2); fxc1 = fxrat; fxc1.type = nodrat->type; fxc1.etype = nodrat->etype; fxc1.xoffset += SZ_LONG; gins(AMOVW, &fxc2, &fxc1); regfree(&fxc2); regfree(&fxc0); regalloc(&nod, t, t); /* should be type float */ gins(AFMOVD, &fxrat, &nod); nodreg(&fxc1, t, NREG+FREGCVI); gins(AFSUB, &fxc1, &nod); a = AFMOVD; if(tt == TFLOAT) a = AFRSP; gins(a, &nod, t); regfree(&nod); if(ft == TULONG) { regalloc(&nod, t, Z); if(tt == TFLOAT) { gins(AFCMPU, t, Z); p->to.type = D_FREG; p->to.reg = FREGZERO; gins(ABGE, Z, Z); p1 = p; gins(AFMOVS, nodfconst(4294967296.), &nod); gins(AFADDS, &nod, t); } else { gins(AFCMPU, t, Z); p->to.type = D_FREG; p->to.reg = FREGZERO; gins(ABGE, Z, Z); p1 = p; gins(AFMOVD, nodfconst(4294967296.), &nod); gins(AFADD, &nod, t); } patch(p1, pc); regfree(&nod); } return; case TINT: case TUINT: case TLONG: case TULONG: case TIND: case TSHORT: case TUSHORT: a = AMOVBZ; break; case TCHAR: case TUCHAR: a = AMOVW; break; } break; } if(a == AGOK) diag(Z, "bad opcode in gmove %T -> %T", f->type, t->type); if(a == AMOVW || a == AFMOVS || a == AFMOVD) if(samaddr(f, t)) return; gins(a, f, t);}voidgins(int a, Node *f, Node *t){ nextpc(); p->as = a; if(f != Z) naddr(f, &p->from); if(t != Z) naddr(t, &p->to); if(debug['g']) print("%P\n", p);}voidgopcode(int o, Node *f1, Node *f2, Node *t){ int a, et; Adr ta; int uns; uns = 0; et = TLONG; if(f1 != Z && f1->type != T) et = f1->type->etype; a = AGOK; switch(o) { case OAS: gmove(f1, t); return; case OASADD: case OADD: a = AADD; if(et == TFLOAT) a = AFADDS; else if(et == TDOUBLE || et == TVLONG) a = AFADD; break; case OASSUB: case OSUB: a = ASUB; if(et == TFLOAT) a = AFSUBS; else if(et == TDOUBLE || et == TVLONG) a = AFSUB; break; case OASOR: case OOR: a = AOR; break; case OASAND: case OAND: a = AAND; if(f1->op == OCONST) a = AANDCC; break; case OASXOR: case OXOR: a = AXOR; break; case OASLSHR: case OLSHR: a = ASRW; break; case OASASHR: case OASHR: a = ASRAW; break; case OASASHL: case OASHL: a = ASLW; /* BUG? */ break; case OFUNC: a = ABL; break; case OASLMUL: case OLMUL: case OASMUL: case OMUL: if(et == TFLOAT) { a = AFMULS; break; } else if(et == TDOUBLE || et == TVLONG) { a = AFMUL; break; } a = AMULLW; break; case OASDIV: case ODIV: if(et == TFLOAT) { a = AFDIVS; break; } else if(et == TDOUBLE || et == TVLONG) { a = AFDIV; break; } a = ADIVW; break; case OASMOD: case OMOD: a = AREM; break; case OASLMOD: case OLMOD: a = AREMU; break; case OASLDIV: case OLDIV: a = ADIVWU; break; case OCOM: a = ANOR; break; case ONEG: a = ANEG; if(et == TFLOAT || et == TDOUBLE || et == TVLONG) a = AFNEG; break; case OEQ: a = ABEQ; goto cmp; case ONE: a = ABNE; goto cmp; case OLT: a = ABLT; goto cmp; case OLE: a = ABLE; goto cmp; case OGE: a = ABGE; goto cmp; case OGT: a = ABGT; goto cmp; case OLO: a = ABLT; goto cmpu; case OLS: a = ABLE; goto cmpu; case OHS: a = ABGE; goto cmpu; case OHI: a = ABGT; goto cmpu; cmpu: uns = 1; cmp: nextpc(); p->as = uns? ACMPU: ACMP; if(et == TFLOAT) p->as = AFCMPU; else if(et == TDOUBLE || et == TVLONG) p->as = AFCMPU; if(f1 != Z) naddr(f1, &p->from); if(t != Z) naddr(t, &p->to); if(f1 == Z || t == Z || f2 != Z) diag(Z, "bad cmp in gopcode %O", o); if(debug['g']) print("%P\n", p); f1 = Z; f2 = Z; t = Z; break; } if(a == AGOK) diag(Z, "bad in gopcode %O", o); nextpc(); p->as = a; if(f1 != Z) naddr(f1, &p->from); if(f2 != Z) { naddr(f2, &ta); p->reg = ta.reg; if(ta.type == D_CONST && ta.offset == 0) { if(R0ISZERO) p->reg = REGZERO; else diag(Z, "REGZERO in gopcode %O", o); } } if(t != Z) naddr(t, &p->to); if(debug['g']) print("%P\n", p);}samaddr(Node *f, Node *t){ if(f->op != t->op) return 0; switch(f->op) { case OREGISTER: if(f->reg != t->reg) break; return 1; } return 0;}voidgbranch(int o){ int a; a = AGOK; switch(o) { case ORETURN: a = ARETURN; break; case OGOTO: a = ABR; break; } nextpc(); if(a == AGOK) { diag(Z, "bad in gbranch %O", o); nextpc(); } p->as = a;}voidpatch(Prog *op, long pc){ op->to.offset = pc; op->to.type = D_BRANCH;}voidgpseudo(int a, Sym *s, Node *n){ nextpc(); p->as = a; p->from.type = D_OREG; p->from.sym = s; p->reg = (profileflg ? 0 : NOPROF); p->from.name = D_EXTERN; if(s->class == CSTATIC) p->from.name = D_STATIC; naddr(n, &p->to); if(a == ADATA || a == AGLOBL) pc--;}intsval(long v){ if(v >= -(1<<15) && v < (1<<15)) return 1; return 0;}intsconst(Node *n){ vlong vv; if(n->op == OCONST) { if(!typefd[n->type->etype]) { vv = n->vconst; if(vv >= -(((vlong)1)<<15) && vv < (((vlong)1)<<15)) return 1; } } return 0;}intuconst(Node *n){ vlong vv; if(n->op == OCONST) { if(!typefd[n->type->etype]) { vv = n->vconst; if(vv >= 0 && vv < (((vlong)1)<<16)) return 1; } } return 0;}longexreg(Type *t){ long o; if(typechlp[t->etype]) { if(exregoffset <= 3) return 0; o = exregoffset; exregoffset--; return o; } if(typefd[t->etype]) { if(exfregoffset <= 16) return 0; o = exfregoffset + NREG; exfregoffset--; return o; } return 0;}schar ewidth[NTYPE] ={ -1, /* [TXXX] */ SZ_CHAR, /* [TCHAR] */ SZ_CHAR, /* [TUCHAR] */ SZ_SHORT, /* [TSHORT] */ SZ_SHORT, /* [TUSHORT] */ SZ_INT, /* [TINT] */ SZ_INT, /* [TUINT] */ SZ_LONG, /* [TLONG] */ SZ_LONG, /* [TULONG] */ SZ_VLONG, /* [TVLONG] */ SZ_VLONG, /* [TUVLONG] */ SZ_FLOAT, /* [TFLOAT] */ SZ_DOUBLE, /* [TDOUBLE] */ SZ_IND, /* [TIND] */ 0, /* [TFUNC] */ -1, /* [TARRAY] */ 0, /* [TVOID] */ -1, /* [TSTRUCT] */ -1, /* [TUNION] */ SZ_INT, /* [TENUM] */};long ncast[NTYPE] ={ 0, /* [TXXX] */ BCHAR|BUCHAR, /* [TCHAR] */ BCHAR|BUCHAR, /* [TUCHAR] */ BSHORT|BUSHORT, /* [TSHORT] */ BSHORT|BUSHORT, /* [TUSHORT] */ BINT|BUINT|BLONG|BULONG|BIND, /* [TINT] */ BINT|BUINT|BLONG|BULONG|BIND, /* [TUINT] */ BINT|BUINT|BLONG|BULONG|BIND, /* [TLONG] */ BINT|BUINT|BLONG|BULONG|BIND, /* [TULONG] */ BVLONG|BUVLONG, /* [TVLONG] */ BVLONG|BUVLONG, /* [TUVLONG] */ BFLOAT, /* [TFLOAT] */ BDOUBLE, /* [TDOUBLE] */ BLONG|BULONG|BIND, /* [TIND] */ 0, /* [TFUNC] */ 0, /* [TARRAY] */ 0, /* [TVOID] */ BSTRUCT, /* [TSTRUCT] */ BUNION, /* [TUNION] */ 0, /* [TENUM] */};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -