If a conditional jump instruction has the same jt and jf, do not perform

the test and jump unconditionally.
This commit is contained in:
jkim 2010-04-22 23:47:19 +00:00
parent 0ce1581c92
commit 42eb898c75
4 changed files with 62 additions and 20 deletions

View File

@ -419,62 +419,77 @@ bpf_jit_compile(struct bpf_insn *prog, u_int nins, size_t *size)
break;
case BPF_JMP|BPF_JA:
JMP(stream.refs[stream.bpf_pc + ins->k] -
stream.refs[stream.bpf_pc]);
JUMP(ins->k);
break;
case BPF_JMP|BPF_JGT|BPF_K:
if (ins->jt == 0 && ins->jf == 0)
if (ins->jt == ins->jf) {
JUMP(ins->jt);
break;
}
CMPid(ins->k, EAX);
JCC(JA, JBE);
break;
case BPF_JMP|BPF_JGE|BPF_K:
if (ins->jt == 0 && ins->jf == 0)
if (ins->jt == ins->jf) {
JUMP(ins->jt);
break;
}
CMPid(ins->k, EAX);
JCC(JAE, JB);
break;
case BPF_JMP|BPF_JEQ|BPF_K:
if (ins->jt == 0 && ins->jf == 0)
if (ins->jt == ins->jf) {
JUMP(ins->jt);
break;
}
CMPid(ins->k, EAX);
JCC(JE, JNE);
break;
case BPF_JMP|BPF_JSET|BPF_K:
if (ins->jt == 0 && ins->jf == 0)
if (ins->jt == ins->jf) {
JUMP(ins->jt);
break;
}
TESTid(ins->k, EAX);
JCC(JNE, JE);
break;
case BPF_JMP|BPF_JGT|BPF_X:
if (ins->jt == 0 && ins->jf == 0)
if (ins->jt == ins->jf) {
JUMP(ins->jt);
break;
}
CMPrd(EDX, EAX);
JCC(JA, JBE);
break;
case BPF_JMP|BPF_JGE|BPF_X:
if (ins->jt == 0 && ins->jf == 0)
if (ins->jt == ins->jf) {
JUMP(ins->jt);
break;
}
CMPrd(EDX, EAX);
JCC(JAE, JB);
break;
case BPF_JMP|BPF_JEQ|BPF_X:
if (ins->jt == 0 && ins->jf == 0)
if (ins->jt == ins->jf) {
JUMP(ins->jt);
break;
}
CMPrd(EDX, EAX);
JCC(JE, JNE);
break;
case BPF_JMP|BPF_JSET|BPF_X:
if (ins->jt == 0 && ins->jf == 0)
if (ins->jt == ins->jf) {
JUMP(ins->jt);
break;
}
TESTrd(EDX, EAX);
JCC(JNE, JE);
break;

View File

@ -473,4 +473,10 @@ typedef void (*emit_func)(bpf_bin_stream *stream, u_int value, u_int n);
} \
} while (0)
#define JUMP(off) do { \
if ((off) != 0) \
JMP(stream.refs[stream.bpf_pc + (off)] - \
stream.refs[stream.bpf_pc]); \
} while (0)
#endif /* _BPF_JIT_MACHDEP_H_ */

View File

@ -440,62 +440,77 @@ bpf_jit_compile(struct bpf_insn *prog, u_int nins, size_t *size)
break;
case BPF_JMP|BPF_JA:
JMP(stream.refs[stream.bpf_pc + ins->k] -
stream.refs[stream.bpf_pc]);
JUMP(ins->k);
break;
case BPF_JMP|BPF_JGT|BPF_K:
if (ins->jt == 0 && ins->jf == 0)
if (ins->jt == ins->jf) {
JUMP(ins->jt);
break;
}
CMPid(ins->k, EAX);
JCC(JA, JBE);
break;
case BPF_JMP|BPF_JGE|BPF_K:
if (ins->jt == 0 && ins->jf == 0)
if (ins->jt == ins->jf) {
JUMP(ins->jt);
break;
}
CMPid(ins->k, EAX);
JCC(JAE, JB);
break;
case BPF_JMP|BPF_JEQ|BPF_K:
if (ins->jt == 0 && ins->jf == 0)
if (ins->jt == ins->jf) {
JUMP(ins->jt);
break;
}
CMPid(ins->k, EAX);
JCC(JE, JNE);
break;
case BPF_JMP|BPF_JSET|BPF_K:
if (ins->jt == 0 && ins->jf == 0)
if (ins->jt == ins->jf) {
JUMP(ins->jt);
break;
}
TESTid(ins->k, EAX);
JCC(JNE, JE);
break;
case BPF_JMP|BPF_JGT|BPF_X:
if (ins->jt == 0 && ins->jf == 0)
if (ins->jt == ins->jf) {
JUMP(ins->jt);
break;
}
CMPrd(EDX, EAX);
JCC(JA, JBE);
break;
case BPF_JMP|BPF_JGE|BPF_X:
if (ins->jt == 0 && ins->jf == 0)
if (ins->jt == ins->jf) {
JUMP(ins->jt);
break;
}
CMPrd(EDX, EAX);
JCC(JAE, JB);
break;
case BPF_JMP|BPF_JEQ|BPF_X:
if (ins->jt == 0 && ins->jf == 0)
if (ins->jt == ins->jf) {
JUMP(ins->jt);
break;
}
CMPrd(EDX, EAX);
JCC(JE, JNE);
break;
case BPF_JMP|BPF_JSET|BPF_X:
if (ins->jt == 0 && ins->jf == 0)
if (ins->jt == ins->jf) {
JUMP(ins->jt);
break;
}
TESTrd(EDX, EAX);
JCC(JNE, JE);
break;

View File

@ -418,4 +418,10 @@ typedef void (*emit_func)(bpf_bin_stream *stream, u_int value, u_int n);
} \
} while (0)
#define JUMP(off) do { \
if ((off) != 0) \
JMP(stream.refs[stream.bpf_pc + (off)] - \
stream.refs[stream.bpf_pc]); \
} while (0)
#endif /* _BPF_JIT_MACHDEP_H_ */