summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2010-04-22 23:47:19 +0000
committerjkim <jkim@FreeBSD.org>2010-04-22 23:47:19 +0000
commit42eb898c75b992137e13abf8bfc18b021635f943 (patch)
tree2b9e849b750f9c695432a137ae52596a7718b41a
parent0ce1581c92eafeba1f652d19f178834c45830d1d (diff)
downloadFreeBSD-src-42eb898c75b992137e13abf8bfc18b021635f943.zip
FreeBSD-src-42eb898c75b992137e13abf8bfc18b021635f943.tar.gz
If a conditional jump instruction has the same jt and jf, do not perform
the test and jump unconditionally.
-rw-r--r--sys/amd64/amd64/bpf_jit_machdep.c35
-rw-r--r--sys/amd64/amd64/bpf_jit_machdep.h6
-rw-r--r--sys/i386/i386/bpf_jit_machdep.c35
-rw-r--r--sys/i386/i386/bpf_jit_machdep.h6
4 files changed, 62 insertions, 20 deletions
diff --git a/sys/amd64/amd64/bpf_jit_machdep.c b/sys/amd64/amd64/bpf_jit_machdep.c
index 6a5793e..fe861d2 100644
--- a/sys/amd64/amd64/bpf_jit_machdep.c
+++ b/sys/amd64/amd64/bpf_jit_machdep.c
@@ -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;
diff --git a/sys/amd64/amd64/bpf_jit_machdep.h b/sys/amd64/amd64/bpf_jit_machdep.h
index aa7f342..01c251f 100644
--- a/sys/amd64/amd64/bpf_jit_machdep.h
+++ b/sys/amd64/amd64/bpf_jit_machdep.h
@@ -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_ */
diff --git a/sys/i386/i386/bpf_jit_machdep.c b/sys/i386/i386/bpf_jit_machdep.c
index e9d9eca..4c2946f 100644
--- a/sys/i386/i386/bpf_jit_machdep.c
+++ b/sys/i386/i386/bpf_jit_machdep.c
@@ -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;
diff --git a/sys/i386/i386/bpf_jit_machdep.h b/sys/i386/i386/bpf_jit_machdep.h
index e82f68a..4ae5494 100644
--- a/sys/i386/i386/bpf_jit_machdep.h
+++ b/sys/i386/i386/bpf_jit_machdep.h
@@ -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_ */
OpenPOWER on IntegriCloud