📄 sub.c
字号:
if(k == TIND) { if(i == TIND) n->type = t1; else if(j == TIND) n->type = t2; } else { /* convert up to at least int */ if(f == 1) while(k < TINT) k += 2; n->type = types[k]; } if(n->op == OSUB) if(i == TIND && j == TIND) { w = n->right->type->link->width; if(w < 1 || n->left->type->link == T || n->left->type->link->width < 1) goto bad; n->type = types[ewidth[TIND] <= ewidth[TLONG]? TLONG: TVLONG]; if(1 && ewidth[TIND] > ewidth[TLONG]){ n1 = new1(OXXX, Z, Z); *n1 = *n; n->op = OCAST; n->left = n1; n->right = Z; n->type = types[TLONG]; } if(w > 1) { n1 = new1(OXXX, Z, Z); *n1 = *n; n->op = ODIV; n->left = n1; n1 = new1(OCONST, Z, Z); n1->vconst = w; n1->type = n->type; n->right = n1; w = vlog(n1); if(w >= 0) { n->op = OASHR; n1->vconst = w; } } return; } if(!sametype(n->type, n->left->type)) { n->left = new1(OCAST, n->left, Z); n->left->type = n->type; if(n->type->etype == TIND) { w = n->type->link->width; if(w < 1) { snap(n->type->link); w = n->type->link->width; if(w < 1) goto bad; } if(w > 1) { n1 = new1(OCONST, Z, Z); n1->vconst = w; n1->type = n->type; n->left = new1(OMUL, n->left, n1); n->left->type = n->type; } } } if(n->right != Z) if(!sametype(n->type, n->right->type)) { n->right = new1(OCAST, n->right, Z); n->right->type = n->type; if(n->type->etype == TIND) { w = n->type->link->width; if(w < 1) { snap(n->type->link); w = n->type->link->width; if(w < 1) goto bad; } if(w != 1) { n1 = new1(OCONST, Z, Z); n1->vconst = w; n1->type = n->type; n->right = new1(OMUL, n->right, n1); n->right->type = n->type; } } } return;bad: diag(n, "pointer addition not fully declared: %T", n->type->link);}/* * try to rewrite shift & mask */voidsimplifyshift(Node *n){ ulong c3; int o, s1, s2, c1, c2; if(!typechlp[n->type->etype]) return; switch(n->op) { default: return; case OASHL: s1 = 0; break; case OLSHR: s1 = 1; break; case OASHR: s1 = 2; break; } if(n->right->op != OCONST) return; if(n->left->op != OAND) return; if(n->left->right->op != OCONST) return; switch(n->left->left->op) { default: return; case OASHL: s2 = 0; break; case OLSHR: s2 = 1; break; case OASHR: s2 = 2; break; } if(n->left->left->right->op != OCONST) return; c1 = n->right->vconst; c2 = n->left->left->right->vconst; c3 = n->left->right->vconst;/* if(debug['h']) print("%.3o %ld %ld %d #%.lux\n", (s1<<3)|s2, c1, c2, topbit(c3), c3);*/ o = n->op; switch((s1<<3)|s2) { case 000: /* (((e <<u c2) & c3) <<u c1) */ c3 >>= c2; c1 += c2; if(c1 >= 32) break; goto rewrite1; case 002: /* (((e >>s c2) & c3) <<u c1) */ if(topbit(c3) >= (32-c2)) break; case 001: /* (((e >>u c2) & c3) <<u c1) */ if(c1 > c2) { c3 <<= c2; c1 -= c2; o = OASHL; goto rewrite1; } c3 <<= c1; if(c1 == c2) goto rewrite0; c1 = c2-c1; o = OLSHR; goto rewrite2; case 022: /* (((e >>s c2) & c3) >>s c1) */ if(c2 <= 0) break; case 012: /* (((e >>s c2) & c3) >>u c1) */ if(topbit(c3) >= (32-c2)) break; goto s11; case 021: /* (((e >>u c2) & c3) >>s c1) */ if(topbit(c3) >= 31 && c2 <= 0) break; goto s11; case 011: /* (((e >>u c2) & c3) >>u c1) */ s11: c3 <<= c2; c1 += c2; if(c1 >= 32) break; o = OLSHR; goto rewrite1; case 020: /* (((e <<u c2) & c3) >>s c1) */ if(topbit(c3) >= 31) break; case 010: /* (((e <<u c2) & c3) >>u c1) */ c3 >>= c1; if(c1 == c2) goto rewrite0; if(c1 > c2) { c1 -= c2; goto rewrite2; } c1 = c2 - c1; o = OASHL; goto rewrite2; } return;rewrite0: /* get rid of both shifts */if(debug['<'])prtree(n, "rewrite0"); *n = *n->left; n->left = n->left->left; n->right->vconst = c3; return;rewrite1: /* get rid of lower shift */if(debug['<'])prtree(n, "rewrite1"); n->left->left = n->left->left->left; n->left->right->vconst = c3; n->right->vconst = c1; n->op = o; return;rewrite2: /* get rid of upper shift */if(debug['<'])prtree(n, "rewrite2"); *n = *n->left; n->right->vconst = c3; n->left->right->vconst = c1; n->left->op = o;}intside(Node *n){loop: if(n != Z) switch(n->op) { case OCAST: case ONOT: case OADDR: case OIND: n = n->left; goto loop; case OCOND: if(side(n->left)) break; n = n->right; case OEQ: case ONE: case OLT: case OGE: case OGT: case OLE: case OADD: case OSUB: case OMUL: case OLMUL: case ODIV: case OLDIV: case OLSHR: case OASHL: case OASHR: case OAND: case OOR: case OXOR: case OMOD: case OLMOD: case OANDAND: case OOROR: case OCOMMA: case ODOT: if(side(n->left)) break; n = n->right; goto loop; case OSIGN: case OSIZE: case OCONST: case OSTRING: case OLSTRING: case ONAME: return 0; } return 1;}intvconst(Node *n){ int i; if(n == Z) goto no; if(n->op != OCONST) goto no; if(n->type == T) goto no; switch(n->type->etype) { case TFLOAT: case TDOUBLE: i = 100; if(n->fconst > i || n->fconst < -i) goto no; i = n->fconst; if(i != n->fconst) goto no; return i; case TVLONG: case TUVLONG: i = n->vconst; if(i != n->vconst) goto no; return i; case TCHAR: case TUCHAR: case TSHORT: case TUSHORT: case TINT: case TUINT: case TLONG: case TULONG: case TIND: i = n->vconst; if(i != n->vconst) goto no; return i; }no: return -159; /* first uninteresting constant */}/* * return log(n) if n is a power of 2 constant */intlog2(uvlong v){ int s, i; uvlong m; s = 0; m = MASK(8*sizeof(uvlong)); for(i=32; i; i>>=1) { m >>= i; if(!(v & m)) { v >>= i; s += i; } } if(v == 1) return s; return -1;}intvlog(Node *n){ if(n->op != OCONST) goto bad; if(typefd[n->type->etype]) goto bad; return log2(n->vconst);bad: return -1;}inttopbit(ulong v){ int i; for(i = -1; v; i++) v >>= 1; return i;}/* * try to cast a constant down * rather than cast a variable up * example: * if(c == 'a') */voidrelcon(Node *l, Node *r){ vlong v; if(l->op != OCONST) return; if(r->op != OCAST) return; if(!nilcast(r->left->type, r->type)) return; switch(r->type->etype) { default: return; case TCHAR: case TUCHAR: case TSHORT: case TUSHORT: v = convvtox(l->vconst, r->type->etype); if(v != l->vconst) return; break; } l->type = r->left->type; *r = *r->left;}intrelindex(int o){ switch(o) { default: diag(Z, "bad in relindex: %O", o); case OEQ: return 0; case ONE: return 1; case OLE: return 2; case OLS: return 3; case OLT: return 4; case OLO: return 5; case OGE: return 6; case OHS: return 7; case OGT: return 8; case OHI: return 9; }}Node*invert(Node *n){ Node *i; if(n == Z || n->op != OLIST) return n; i = n; for(n = n->left; n != Z; n = n->left) { if(n->op != OLIST) break; i->left = n->right; n->right = i; i = n; } i->left = n; return i;}intbitno(long b){ int i; for(i=0; i<32; i++) if(b & (1L<<i)) return i; diag(Z, "bad in bitno"); return 0;}longtypebitor(long a, long b){ long c; c = a | b; if(a & b) if((a & b) == BLONG) c |= BVLONG; /* long long => vlong */ else warn(Z, "once is enough: %Q", a & b); return c;}voiddiag(Node *n, char *fmt, ...){ char buf[STRINGSZ]; va_list arg; va_start(arg, fmt); vseprint(buf, buf+sizeof(buf), fmt, arg); va_end(arg); Bprint(&diagbuf, "%L %s\n", (n==Z)? nearln: n->lineno, buf); if(debug['X']){ Bflush(&diagbuf); abort(); } if(n != Z) if(debug['v']) prtree(n, "diagnostic"); nerrors++; if(nerrors > 10) { Bprint(&diagbuf, "too many errors\n"); errorexit(); }}voidwarn(Node *n, char *fmt, ...){ char buf[STRINGSZ]; va_list arg; if(debug['w']) { Bprint(&diagbuf, "warning: "); va_start(arg, fmt); vseprint(buf, buf+sizeof(buf), fmt, arg); va_end(arg); Bprint(&diagbuf, "%L %s\n", (n==Z)? nearln: n->lineno, buf); if(n != Z) if(debug['v']) prtree(n, "warning"); }}voidyyerror(char *fmt, ...){ char buf[STRINGSZ]; va_list arg; /* * hack to intercept message from yaccpar */ if(strcmp(fmt, "syntax error") == 0) { yyerror("syntax error, last name: %s", symb); return; } va_start(arg, fmt); vseprint(buf, buf+sizeof(buf), fmt, arg); va_end(arg); Bprint(&diagbuf, "%L %s\n", lineno, buf); nerrors++; if(nerrors > 10) { Bprint(&diagbuf, "too many errors\n"); errorexit(); }}voidfatal(Node *n, char *fmt, ...){ char buf[STRINGSZ]; va_list arg; va_start(arg, fmt); vseprint(buf, buf+sizeof(buf), fmt, arg); va_end(arg); Bprint(&diagbuf, "%L %s\n", (n==Z)? nearln: n->lineno, buf); if(debug['X']){ Bflush(&diagbuf); abort(); } if(n != Z) if(debug['v']) prtree(n, "diagnostic"); nerrors++; errorexit();}ulong thash1 = 0x2edab8c9;ulong thash2 = 0x1dc74fb8;ulong thash3 = 0x1f241331;ulong thash[NALLTYPES];Init thashinit[] ={ TXXX, 0x17527bbd, 0, TCHAR, 0x5cedd32b, 0, TUCHAR, 0x552c4454, 0, TSHORT, 0x63040b4b, 0, TUSHORT, 0x32a45878, 0, TINT, 0x4151d5bd, 0, TUINT, 0x5ae707d6, 0, TLONG, 0x5ef20f47, 0, TULONG, 0x36d8eb8f, 0, TVLONG, 0x6e5e9590, 0, TUVLONG, 0x75910105, 0, TFLOAT, 0x25fd7af1, 0, TDOUBLE, 0x7c40a1b2, 0, TIND, 0x1b832357, 0, TFUNC, 0x6babc9cb, 0, TARRAY, 0x7c50986d, 0, TVOID, 0x44112eff, 0, TSTRUCT, 0x7c2da3bf, 0, TUNION, 0x3eb25e98, 0, TENUM, 0x44b54f61, 0, TFILE, 0x19242ac3, 0, TOLD, 0x22b15988, 0, TDOT, 0x0204f6b3, 0, -1, 0, 0,};char* bnames[NALIGN];Init bnamesinit[] ={ Axxx, 0, "Axxx", Ael1, 0, "el1", Ael2, 0, "el2", Asu2, 0, "su2", Aarg0, 0, "arg0", Aarg1, 0, "arg1", Aarg2, 0, "arg2", Aaut3, 0, "aut3", -1, 0, 0,};char* tnames[NALLTYPES];Init tnamesinit[] ={ TXXX, 0, "TXXX", TCHAR, 0, "CHAR", TUCHAR, 0, "UCHAR", TSHORT, 0, "SHORT", TUSHORT, 0, "USHORT", TINT, 0, "INT", TUINT, 0, "UINT", TLONG, 0, "LONG", TULONG, 0, "ULONG", TVLONG, 0, "VLONG", TUVLONG, 0, "UVLONG", TFLOAT, 0, "FLOAT", TDOUBLE, 0, "DOUBLE", TIND, 0, "IND", TFUNC, 0, "FUNC", TARRAY, 0, "ARRAY", TVOID, 0, "VOID", TSTRUCT, 0, "STRUCT", TUNION, 0, "UNION", TENUM, 0, "ENUM", TFILE, 0, "FILE", TOLD, 0, "OLD", TDOT, 0, "DOT", -1, 0, 0,};char* gnames[NGTYPES];Init gnamesinit[] ={ GXXX, 0, "GXXX", GCONSTNT, 0, "CONST", GVOLATILE, 0, "VOLATILE", GVOLATILE|GCONSTNT, 0, "CONST-VOLATILE", -1, 0, 0,};char* qnames[NALLTYPES];Init qnamesinit[] ={ TXXX, 0, "TXXX", TCHAR, 0, "CHAR", TUCHAR, 0, "UCHAR", TSHORT, 0, "SHORT", TUSHORT, 0, "USHORT", TINT, 0, "INT", TUINT, 0, "UINT", TLONG, 0, "LONG", TULONG, 0, "ULONG", TVLONG, 0, "VLONG", TUVLONG, 0, "UVLONG", TFLOAT, 0, "FLOAT", TDOUBLE, 0, "DOUBLE",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -