*** tcc.c.orig Fri Jul 7 17:08:06 2006 --- tcc.c Fri Jul 7 17:26:04 2006 *************** void gen_opif(int op) *** 5469,5474 **** --- 5469,5550 ---- } } + /* handle long long ops with constant propogation */ + void gen_opil(int op) + { + int c1, c2, n; + SValue *v1, *v2; + int ifc; + long long int fc; + unsigned long long int ufc; + + v1 = vtop - 1; + v2 = vtop; + /* currently, we cannot do computations with forward symbols */ + c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; + c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; + if (c1 && c2) { + fc = v2->c.ll; + ifc = v2->c.i; + ufc = v2->c.ull; + switch(op) { + case '+': v1->c.ll += fc; break; + case '-': v1->c.ll -= fc; break; + case '&': v1->c.ll &= fc; break; + case '^': v1->c.ll ^= fc; break; + case '|': v1->c.ll |= fc; break; + case '*': v1->c.ll *= fc; break; + + case TOK_PDIV: + case '/': + case '%': + case TOK_UDIV: + case TOK_UMOD: + /* if division by zero, generate explicit division */ + if (fc == 0) { + if (const_wanted) + error("division by zero in constant"); + goto general_case; + } + switch(op) { + default: v1->c.ll /= fc; break; + case '%': v1->c.ll %= fc; break; + case TOK_UDIV: v1->c.ll = v1->c.ull / fc; break; + case TOK_UMOD: v1->c.ll = v1->c.ull % fc; break; + } + break; + case TOK_SHL: v1->c.ll <<= ifc; break; + case TOK_SHR: v1->c.ll = v1->c.ull >> ifc; break; + case TOK_SAR: v1->c.ll >>= ifc; break; + /* tests */ + case TOK_ULT: v1->c.i = v1->c.ull < ufc; break; + case TOK_UGE: v1->c.i = v1->c.ull >= ufc; break; + case TOK_EQ: v1->c.i = v1->c.ll == fc; break; + case TOK_NE: v1->c.i = v1->c.ll != fc; break; + case TOK_ULE: v1->c.i = v1->c.ull <= ufc; break; + case TOK_UGT: v1->c.i = v1->c.ull > ufc; break; + case TOK_LT: v1->c.i = v1->c.ll < fc; break; + case TOK_GE: v1->c.i = v1->c.ll >= fc; break; + case TOK_LE: v1->c.i = v1->c.ll <= fc; break; + case TOK_GT: v1->c.i = v1->c.ll > fc; break; + /* logical */ + case TOK_LAND: v1->c.ll = v1->c.ll && fc; break; + case TOK_LOR: v1->c.ll = v1->c.ll || fc; break; + default: + goto general_case; + } + vtop--; + } else { + general_case: + if (!nocode_wanted) { + /* call low level op generator */ + gen_opl(op); + } else { + vtop--; + } + } + } + static int pointed_size(CType *type) { int align; *************** void gen_op(int op) *** 5661,5667 **** if (is_float(t)) gen_opif(op); else if ((t & VT_BTYPE) == VT_LLONG) ! gen_opl(op); else gen_opic(op); if (op >= TOK_ULT && op <= TOK_GT) { --- 5737,5743 ---- if (is_float(t)) gen_opif(op); else if ((t & VT_BTYPE) == VT_LLONG) ! gen_opil(op); else gen_opic(op); if (op >= TOK_ULT && op <= TOK_GT) {