diff options
-rw-r--r-- | gencode.c | 14 | ||||
-rw-r--r-- | optimize.c | 89 |
2 files changed, 45 insertions, 58 deletions
@@ -21,7 +21,7 @@ */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.165 2002-06-01 23:22:57 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.166 2002-06-11 05:30:39 itojun Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -3539,16 +3539,16 @@ gen_relation(code, a0, a1, reversed) s0 = xfer_to_x(a1); s1 = xfer_to_a(a0); - s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X); - b = new_block(JMP(code)); - if (code == BPF_JGT || code == BPF_JGE) { - reversed = !reversed; - b->s.k = 0x80000000; + if (code == BPF_JEQ) { + s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X); + b = new_block(JMP(code)); + sappend(s1, s2); } + else + b = new_block(BPF_JMP|code|BPF_X); if (reversed) gen_not(b); - sappend(s1, s2); sappend(s0, s1); sappend(a1->s, s0); sappend(a0->s, a1->s); @@ -22,7 +22,7 @@ */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.72 2002-03-24 23:21:51 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.73 2002-06-11 05:30:40 itojun Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -664,7 +664,7 @@ opt_peep(b) return; last = s; - while (1) { + for (/*empty*/; /*empty*/; s = next) { s = this_op(s); if (s == 0) break; @@ -707,23 +707,23 @@ opt_peep(b) * any local dependencies. */ if (ATOMELEM(b->out_use, X_ATOM)) - break; + continue; if (next->s.code != (BPF_LDX|BPF_MSH|BPF_B)) add = next; else add = this_op(next->next); if (add == 0 || add->s.code != (BPF_ALU|BPF_ADD|BPF_X)) - break; + continue; tax = this_op(add->next); if (tax == 0 || tax->s.code != (BPF_MISC|BPF_TAX)) - break; + continue; ild = this_op(tax->next); if (ild == 0 || BPF_CLASS(ild->s.code) != BPF_LD || BPF_MODE(ild->s.code) != BPF_IND) - break; + continue; /* * XXX We need to check that X is not * subsequently used. We know we can eliminate the @@ -753,57 +753,45 @@ opt_peep(b) tax->s.code = NOP; done = 0; } - s = next; } /* * If we have a subtract to do a comparison, and the X register * is a known constant, we can merge this value into the * comparison. */ - if (last->s.code == (BPF_ALU|BPF_SUB|BPF_X) && - !ATOMELEM(b->out_use, A_ATOM)) { - val = b->val[X_ATOM]; - if (vmap[val].is_const) { - int op; - - b->s.k += vmap[val].const_val; - op = BPF_OP(b->s.code); - if (op == BPF_JGT || op == BPF_JGE) { - struct block *t = JT(b); - JT(b) = JF(b); - JF(b) = t; - b->s.k += 0x80000000; + if (BPF_OP(b->s.code) == BPF_JEQ) { + if (last->s.code == (BPF_ALU|BPF_SUB|BPF_X) && + !ATOMELEM(b->out_use, A_ATOM)) { + val = b->val[X_ATOM]; + if (vmap[val].is_const) { + /* + * sub x -> nop + * jeq #y jeq #(x+y) + */ + b->s.k += vmap[val].const_val; + last->s.code = NOP; + done = 0; + } else if (b->s.k == 0) { + /* + * sub #x -> nop + * jeq #0 jeq #x + */ + last->s.code = NOP; + b->s.code = BPF_CLASS(b->s.code) | + BPF_OP(b->s.code) | BPF_X; + done = 0; } - last->s.code = NOP; - done = 0; - } else if (b->s.k == 0) { - /* - * sub x -> nop - * j #0 j x - */ - last->s.code = NOP; - b->s.code = BPF_CLASS(b->s.code) | BPF_OP(b->s.code) | - BPF_X; - done = 0; } - } - /* - * Likewise, a constant subtract can be simplified. - */ - else if (last->s.code == (BPF_ALU|BPF_SUB|BPF_K) && - !ATOMELEM(b->out_use, A_ATOM)) { - int op; + /* + * Likewise, a constant subtract can be simplified. + */ + else if (last->s.code == (BPF_ALU|BPF_SUB|BPF_K) && + !ATOMELEM(b->out_use, A_ATOM)) { - b->s.k += last->s.k; - last->s.code = NOP; - op = BPF_OP(b->s.code); - if (op == BPF_JGT || op == BPF_JGE) { - struct block *t = JT(b); - JT(b) = JF(b); - JF(b) = t; - b->s.k += 0x80000000; + last->s.code = NOP; + b->s.k += last->s.k; + done = 0; } - done = 0; } /* * and #k nop @@ -996,18 +984,17 @@ opt_stmt(s, val, alter) * that is 0, and simplify. This may not seem like * much of a simplification but it could open up further * optimizations. - * XXX We could also check for mul by 1, and -1, etc. + * XXX We could also check for mul by 1, etc. */ if (alter && vmap[val[A_ATOM]].is_const && vmap[val[A_ATOM]].const_val == 0) { - if (op == BPF_ADD || op == BPF_OR || - op == BPF_LSH || op == BPF_RSH || op == BPF_SUB) { + if (op == BPF_ADD || op == BPF_OR) { s->code = BPF_MISC|BPF_TXA; vstore(s, &val[A_ATOM], val[X_ATOM], alter); break; } else if (op == BPF_MUL || op == BPF_DIV || - op == BPF_AND) { + op == BPF_AND || op == BPF_LSH || op == BPF_RSH) { s->code = BPF_LD|BPF_IMM; s->k = 0; vstore(s, &val[A_ATOM], K(s->k), alter); |