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;