Module Name: src
Committed By: alnsn
Date: Tue Jul 22 08:20:08 UTC 2014
Modified Files:
src/sys/net: bpfjit.c
Log Message:
Don't use scratch registers for X and to restore A after BPF_COPX call.
To generate a diff of this commit:
cvs rdiff -u -r1.28 -r1.29 src/sys/net/bpfjit.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/net/bpfjit.c
diff -u src/sys/net/bpfjit.c:1.28 src/sys/net/bpfjit.c:1.29
--- src/sys/net/bpfjit.c:1.28 Sun Jul 13 21:54:46 2014
+++ src/sys/net/bpfjit.c Tue Jul 22 08:20:08 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: bpfjit.c,v 1.28 2014/07/13 21:54:46 alnsn Exp $ */
+/* $NetBSD: bpfjit.c,v 1.29 2014/07/22 08:20:08 alnsn Exp $ */
/*-
* Copyright (c) 2011-2014 Alexander Nasonov.
@@ -31,9 +31,9 @@
#include <sys/cdefs.h>
#ifdef _KERNEL
-__KERNEL_RCSID(0, "$NetBSD: bpfjit.c,v 1.28 2014/07/13 21:54:46 alnsn Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bpfjit.c,v 1.29 2014/07/22 08:20:08 alnsn Exp $");
#else
-__RCSID("$NetBSD: bpfjit.c,v 1.28 2014/07/13 21:54:46 alnsn Exp $");
+__RCSID("$NetBSD: bpfjit.c,v 1.29 2014/07/22 08:20:08 alnsn Exp $");
#endif
#include <sys/types.h>
@@ -89,11 +89,12 @@ __RCSID("$NetBSD: bpfjit.c,v 1.28 2014/0
#define BJ_BUF SLJIT_SAVED_REG1
//#define BJ_ARGS SLJIT_SAVED_REG2
#define BJ_BUFLEN SLJIT_SAVED_REG3
+#define BJ_XREG SLJIT_SAVED_EREG1
+#define BJ_ASAVE SLJIT_SAVED_EREG2
#define BJ_AREG SLJIT_SCRATCH_REG1
#define BJ_TMP1REG SLJIT_SCRATCH_REG2
#define BJ_TMP2REG SLJIT_SCRATCH_REG3
-#define BJ_XREG SLJIT_TEMPORARY_EREG1
-#define BJ_TMP3REG SLJIT_TEMPORARY_EREG2
+#define BJ_TMP3REG SLJIT_TEMPORARY_EREG1
#ifdef _KERNEL
#define MAX_MEMWORDS BPF_MAX_MEMWORDS
@@ -118,11 +119,12 @@ __RCSID("$NetBSD: bpfjit.c,v 1.28 2014/0
typedef unsigned int bpfjit_hint_t;
#define BJ_HINT_ABS 0x01 /* packet read at absolute offset */
#define BJ_HINT_IND 0x02 /* packet read at variable offset */
-#define BJ_HINT_COP 0x04 /* BPF_COP or BPF_COPX instruction */
-#define BJ_HINT_COPX 0x08 /* BPF_COPX instruction */
-#define BJ_HINT_XREG 0x10 /* BJ_XREG is needed */
-#define BJ_HINT_LDX 0x20 /* BPF_LDX instruction */
-#define BJ_HINT_PKT (BJ_HINT_ABS|BJ_HINT_IND) /* packet read */
+#define BJ_HINT_MSH 0x04 /* BPF_MSH instruction */
+#define BJ_HINT_COP 0x08 /* BPF_COP or BPF_COPX instruction */
+#define BJ_HINT_COPX 0x10 /* BPF_COPX instruction */
+#define BJ_HINT_XREG 0x20 /* BJ_XREG is needed */
+#define BJ_HINT_LDX 0x40 /* BPF_LDX instruction */
+#define BJ_HINT_PKT (BJ_HINT_ABS|BJ_HINT_IND|BJ_HINT_MSH)
/*
* Datatype for Array Bounds Check Elimination (ABC) pass.
@@ -257,17 +259,29 @@ nscratches(bpfjit_hint_t hints)
if (hints & BJ_HINT_COP)
rv = 3; /* calls copfunc with three arguments */
+ if (hints & BJ_HINT_COPX)
+ rv = 4; /* uses BJ_TMP3REG */
+
+ return rv;
+}
+
+/*
+ * Return a number of saved registers to pass
+ * to sljit_emit_enter() function.
+ */
+static sljit_si
+nsaveds(bpfjit_hint_t hints)
+{
+ sljit_si rv = 3;
+
if (hints & BJ_HINT_XREG)
rv = 4; /* uses BJ_XREG */
#ifdef _KERNEL
if (hints & BJ_HINT_LDX)
- rv = 5; /* uses BJ_TMP3REG */
+ rv = 5; /* uses BJ_ASAVE */
#endif
- if (hints & BJ_HINT_COPX)
- rv = 5; /* uses BJ_TMP3REG */
-
return rv;
}
@@ -518,26 +532,16 @@ emit_xcall(struct sljit_compiler *compil
int dst, struct sljit_jump ***ret0, size_t *ret0_size, size_t *ret0_maxsize,
uint32_t (*fn)(const struct mbuf *, uint32_t, int *))
{
-#if BJ_XREG == SLJIT_RETURN_REG || \
- BJ_XREG == SLJIT_SCRATCH_REG1 || \
- BJ_XREG == SLJIT_SCRATCH_REG2 || \
- BJ_XREG == SLJIT_SCRATCH_REG3 || \
- BJ_TMP3REG == SLJIT_RETURN_REG || \
- BJ_TMP3REG == SLJIT_SCRATCH_REG1 || \
- BJ_TMP3REG == SLJIT_SCRATCH_REG2 || \
- BJ_TMP3REG == SLJIT_SCRATCH_REG3
-#error "Not supported assignment of registers."
-#endif
struct sljit_jump *jump;
int status;
- BJ_ASSERT(dst != BJ_TMP2REG && dst != BJ_TMP3REG);
+ BJ_ASSERT(dst != BJ_ASAVE);
if (BPF_CLASS(pc->code) == BPF_LDX) {
/* save A */
status = sljit_emit_op1(compiler,
SLJIT_MOV,
- BJ_TMP3REG, 0,
+ BJ_ASAVE, 0,
BJ_AREG, 0);
if (status != SLJIT_SUCCESS)
return status;
@@ -633,7 +637,7 @@ emit_xcall(struct sljit_compiler *compil
status = sljit_emit_op1(compiler,
SLJIT_MOV,
BJ_AREG, 0,
- BJ_TMP3REG, 0);
+ BJ_ASAVE, 0);
if (status != SLJIT_SUCCESS)
return status;
}
@@ -650,11 +654,7 @@ emit_cop(struct sljit_compiler *compiler
const bpf_ctx_t *bc, const struct bpf_insn *pc,
struct sljit_jump ***ret0, size_t *ret0_size, size_t *ret0_maxsize)
{
-#if BJ_XREG == SLJIT_RETURN_REG || \
- BJ_XREG == SLJIT_SCRATCH_REG1 || \
- BJ_XREG == SLJIT_SCRATCH_REG2 || \
- BJ_XREG == SLJIT_SCRATCH_REG3 || \
- BJ_TMP3REG == SLJIT_SCRATCH_REG1 || \
+#if BJ_TMP3REG == SLJIT_SCRATCH_REG1 || \
BJ_TMP3REG == SLJIT_SCRATCH_REG2 || \
BJ_TMP3REG == SLJIT_SCRATCH_REG3
#error "Not supported assignment of registers."
@@ -1105,13 +1105,6 @@ emit_division(struct sljit_compiler *com
{
int status;
-#if BJ_XREG == SLJIT_RETURN_REG || \
- BJ_XREG == SLJIT_SCRATCH_REG1 || \
- BJ_XREG == SLJIT_SCRATCH_REG2 || \
- BJ_AREG == SLJIT_SCRATCH_REG2
-#error "Not supported assignment of registers."
-#endif
-
#if BJ_AREG != SLJIT_SCRATCH_REG1
status = sljit_emit_op1(compiler,
SLJIT_MOV,
@@ -1285,6 +1278,11 @@ optimize_pass1(const bpf_ctx_t *bc, cons
*initmask |= invalid & BJ_INIT_MBIT(insns[i].k);
}
+ if (BPF_MODE(insns[i].code) == BPF_MSH &&
+ BPF_SIZE(insns[i].code) == BPF_B) {
+ *hints |= BJ_HINT_MSH;
+ }
+
invalid &= ~BJ_INIT_XBIT;
continue;
@@ -2109,8 +2107,8 @@ bpfjit_generate_code(const bpf_ctx_t *bc
sljit_compiler_verbose(compiler, stderr);
#endif
- status = sljit_emit_enter(compiler,
- 2, nscratches(hints), 3, sizeof(struct bpfjit_stack));
+ status = sljit_emit_enter(compiler, 2, nscratches(hints),
+ nsaveds(hints), sizeof(struct bpfjit_stack));
if (status != SLJIT_SUCCESS)
goto fail;