From owner-svn-src-projects@FreeBSD.ORG Thu Dec 6 20:08:04 2012 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 5F63C7DA; Thu, 6 Dec 2012 20:08:04 +0000 (UTC) (envelope-from jkim@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 3947D8FC08; Thu, 6 Dec 2012 20:08:04 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id qB6K84TG024914; Thu, 6 Dec 2012 20:08:04 GMT (envelope-from jkim@svn.freebsd.org) Received: (from jkim@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id qB6K847O024913; Thu, 6 Dec 2012 20:08:04 GMT (envelope-from jkim@svn.freebsd.org) Message-Id: <201212062008.qB6K847O024913@svn.freebsd.org> From: Jung-uk Kim Date: Thu, 6 Dec 2012 20:08:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r243958 - projects/bpfjit/sys/net X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 06 Dec 2012 20:08:04 -0000 Author: jkim Date: Thu Dec 6 20:08:03 2012 New Revision: 243958 URL: http://svnweb.freebsd.org/changeset/base/243958 Log: Simplify and optimize main decode loop. Modified: projects/bpfjit/sys/net/bpfjit.c Modified: projects/bpfjit/sys/net/bpfjit.c ============================================================================== --- projects/bpfjit/sys/net/bpfjit.c Thu Dec 6 19:43:48 2012 (r243957) +++ projects/bpfjit/sys/net/bpfjit.c Thu Dec 6 20:08:03 2012 (r243958) @@ -1197,7 +1197,6 @@ bpfjit_generate_code(struct bpf_insn *in size_t i; int status; int branching, negate; - unsigned int rval, mode, src; int ntmp; unsigned int locals_size; unsigned int minm, maxm; /* min/max k for M[k] */ @@ -1352,229 +1351,164 @@ bpfjit_generate_code(struct bpf_insn *in } pc = &insns[i]; - switch (BPF_CLASS(pc->code)) { + switch (pc->code) { default: goto fail; - case BPF_LD: - /* BPF_LD+BPF_IMM A <- k */ - if (pc->code == (BPF_LD|BPF_IMM)) { - status = sljit_emit_op1(compiler, - SLJIT_MOV, - BPFJIT_A, 0, - SLJIT_IMM, (uint32_t)pc->k); - if (status != SLJIT_SUCCESS) - goto fail; - - continue; - } - - /* BPF_LD+BPF_MEM A <- M[k] */ - if (pc->code == (BPF_LD|BPF_MEM)) { - if (pc->k < minm || pc->k > maxm) - goto fail; - status = sljit_emit_op1(compiler, - SLJIT_MOV_UI, - BPFJIT_A, 0, - SLJIT_MEM1(SLJIT_LOCALS_REG), - mem_local_offset(pc->k, minm)); - if (status != SLJIT_SUCCESS) - goto fail; - - continue; - } - - /* BPF_LD+BPF_W+BPF_LEN A <- len */ - if (pc->code == (BPF_LD|BPF_W|BPF_LEN)) { - status = sljit_emit_op1(compiler, - SLJIT_MOV, - BPFJIT_A, 0, - BPFJIT_WIRELEN, 0); - if (status != SLJIT_SUCCESS) - goto fail; - - continue; - } - - mode = BPF_MODE(pc->code); - if (mode != BPF_ABS && mode != BPF_IND) - goto fail; + case BPF_LD|BPF_IMM: + status = sljit_emit_op1(compiler, + SLJIT_MOV, + BPFJIT_A, 0, + SLJIT_IMM, (uint32_t)pc->k); + break; - status = emit_pkt_read(compiler, pc, - to_mchain_jump, ret0, &ret0_size); - if (status != SLJIT_SUCCESS) + case BPF_LD|BPF_MEM: + if (pc->k < minm || pc->k > maxm) goto fail; + status = sljit_emit_op1(compiler, + SLJIT_MOV_UI, + BPFJIT_A, 0, + SLJIT_MEM1(SLJIT_LOCALS_REG), + mem_local_offset(pc->k, minm)); + break; - continue; - - case BPF_LDX: - mode = BPF_MODE(pc->code); - - /* BPF_LDX+BPF_W+BPF_IMM X <- k */ - if (mode == BPF_IMM) { - if (BPF_SIZE(pc->code) != BPF_W) - goto fail; - status = sljit_emit_op1(compiler, - SLJIT_MOV, - BPFJIT_X, 0, - SLJIT_IMM, (uint32_t)pc->k); - if (status != SLJIT_SUCCESS) - goto fail; - - continue; - } - - /* BPF_LDX+BPF_W+BPF_LEN X <- len */ - if (mode == BPF_LEN) { - if (BPF_SIZE(pc->code) != BPF_W) - goto fail; - status = sljit_emit_op1(compiler, - SLJIT_MOV, - BPFJIT_X, 0, - BPFJIT_WIRELEN, 0); - if (status != SLJIT_SUCCESS) - goto fail; - - continue; - } - - /* BPF_LDX+BPF_W+BPF_MEM X <- M[k] */ - if (mode == BPF_MEM) { - if (BPF_SIZE(pc->code) != BPF_W) - goto fail; - if (pc->k < minm || pc->k > maxm) - goto fail; - status = sljit_emit_op1(compiler, - SLJIT_MOV_UI, - BPFJIT_X, 0, - SLJIT_MEM1(SLJIT_LOCALS_REG), - mem_local_offset(pc->k, minm)); - if (status != SLJIT_SUCCESS) - goto fail; + case BPF_LD|BPF_W|BPF_LEN: + status = sljit_emit_op1(compiler, + SLJIT_MOV, + BPFJIT_A, 0, + BPFJIT_WIRELEN, 0); + break; + + case BPF_LD|BPF_W|BPF_ABS: + case BPF_LD|BPF_H|BPF_ABS: + case BPF_LD|BPF_B|BPF_ABS: + case BPF_LD|BPF_W|BPF_IND: + case BPF_LD|BPF_H|BPF_IND: + case BPF_LD|BPF_B|BPF_IND: + status = emit_pkt_read(compiler, pc, to_mchain_jump, + ret0, &ret0_size); + break; - continue; - } + case BPF_LDX|BPF_IMM: + status = sljit_emit_op1(compiler, + SLJIT_MOV, + BPFJIT_X, 0, + SLJIT_IMM, (uint32_t)pc->k); + break; - /* BPF_LDX+BPF_B+BPF_MSH X <- 4*(P[k:1]&0xf) */ - if (mode != BPF_MSH || BPF_SIZE(pc->code) != BPF_B) - goto fail; + case BPF_LDX|BPF_W|BPF_LEN: + status = sljit_emit_op1(compiler, + SLJIT_MOV, + BPFJIT_X, 0, + BPFJIT_WIRELEN, 0); + break; - status = emit_msh(compiler, pc, - to_mchain_jump, ret0, &ret0_size); - if (status != SLJIT_SUCCESS) + case BPF_LDX|BPF_MEM: + if (pc->k < minm || pc->k > maxm) goto fail; + status = sljit_emit_op1(compiler, + SLJIT_MOV_UI, + BPFJIT_X, 0, + SLJIT_MEM1(SLJIT_LOCALS_REG), + mem_local_offset(pc->k, minm)); + break; - continue; + case BPF_LDX|BPF_MSH|BPF_B: + status = emit_msh(compiler, pc, to_mchain_jump, + ret0, &ret0_size); + break; case BPF_ST: - if (pc->code != BPF_ST || pc->k < minm || pc->k > maxm) + if (pc->k < minm || pc->k > maxm) goto fail; - status = sljit_emit_op1(compiler, SLJIT_MOV_UI, SLJIT_MEM1(SLJIT_LOCALS_REG), mem_local_offset(pc->k, minm), BPFJIT_A, 0); - if (status != SLJIT_SUCCESS) - goto fail; - - continue; + break; case BPF_STX: - if (pc->code != BPF_STX || pc->k < minm || pc->k > maxm) + if (pc->k < minm || pc->k > maxm) goto fail; - status = sljit_emit_op1(compiler, SLJIT_MOV_UI, SLJIT_MEM1(SLJIT_LOCALS_REG), mem_local_offset(pc->k, minm), BPFJIT_X, 0); - if (status != SLJIT_SUCCESS) - goto fail; - - continue; - - case BPF_ALU: - - if (pc->code == (BPF_ALU|BPF_NEG)) { - status = sljit_emit_op1(compiler, - SLJIT_NEG, - BPFJIT_A, 0, - BPFJIT_A, 0); - if (status != SLJIT_SUCCESS) - goto fail; + break; - continue; - } - - if (BPF_OP(pc->code) != BPF_DIV) { - status = sljit_emit_op2(compiler, - bpf_alu_to_sljit_op(pc), - BPFJIT_A, 0, - BPFJIT_A, 0, - kx_to_reg(pc), kx_to_reg_arg(pc)); - if (status != SLJIT_SUCCESS) - goto fail; - - continue; - } + case BPF_ALU|BPF_NEG: + status = sljit_emit_op1(compiler, + SLJIT_NEG, + BPFJIT_A, 0, + BPFJIT_A, 0); + break; - /* BPF_DIV */ + case BPF_ALU|BPF_ADD|BPF_X: + case BPF_ALU|BPF_SUB|BPF_X: + case BPF_ALU|BPF_MUL|BPF_X: + case BPF_ALU|BPF_AND|BPF_X: + case BPF_ALU|BPF_OR|BPF_X: + case BPF_ALU|BPF_LSH|BPF_X: + case BPF_ALU|BPF_RSH|BPF_X: + case BPF_ALU|BPF_ADD|BPF_K: + case BPF_ALU|BPF_SUB|BPF_K: + case BPF_ALU|BPF_MUL|BPF_K: + case BPF_ALU|BPF_AND|BPF_K: + case BPF_ALU|BPF_OR|BPF_K: + case BPF_ALU|BPF_LSH|BPF_K: + case BPF_ALU|BPF_RSH|BPF_K: + status = sljit_emit_op2(compiler, + bpf_alu_to_sljit_op(pc), + BPFJIT_A, 0, + BPFJIT_A, 0, + kx_to_reg(pc), kx_to_reg_arg(pc)); + break; - src = BPF_SRC(pc->code); - if (src != BPF_X && src != BPF_K) + case BPF_ALU|BPF_DIV|BPF_X: + /* division by zero? */ + jump = sljit_emit_cmp(compiler, + SLJIT_C_EQUAL|SLJIT_INT_OP, + BPFJIT_X, 0, + SLJIT_IMM, 0); + if (jump == NULL) goto fail; + ret0[ret0_size++] = jump; + status = emit_division(compiler, BPFJIT_X, 0); + break; + case BPF_ALU|BPF_DIV|BPF_K: /* division by zero? */ - if (src == BPF_X) { - jump = sljit_emit_cmp(compiler, - SLJIT_C_EQUAL|SLJIT_INT_OP, - BPFJIT_X, 0, - SLJIT_IMM, 0); - if (jump == NULL) - goto fail; - ret0[ret0_size++] = jump; - } else if (pc->k == 0) { + if (pc->k == 0) { jump = sljit_emit_jump(compiler, SLJIT_JUMP); if (jump == NULL) goto fail; ret0[ret0_size++] = jump; - } - - if (src == BPF_X) { - status = emit_division(compiler, BPFJIT_X, 0); - if (status != SLJIT_SUCCESS) - goto fail; - } else if (pc->k != 0) { - if (pc->k & (pc->k - 1)) { - status = emit_division(compiler, - SLJIT_IMM, (uint32_t)pc->k); - } else { - status = emit_pow2_division(compiler, - (uint32_t)pc->k); - } - if (status != SLJIT_SUCCESS) - goto fail; - } - - continue; - - case BPF_JMP: - - switch (BPF_OP(pc->code)) { - case BPF_JA: + } else if ((pc->k & (pc->k - 1)) == 0) { + status = emit_pow2_division(compiler, + (uint32_t)pc->k); + } else { + status = emit_division(compiler, SLJIT_IMM, + (uint32_t)pc->k); + } + break; + + case BPF_JMP|BPF_JA: + case BPF_JMP|BPF_JGT|BPF_K: + case BPF_JMP|BPF_JGE|BPF_K: + case BPF_JMP|BPF_JEQ|BPF_K: + case BPF_JMP|BPF_JSET|BPF_K: + case BPF_JMP|BPF_JGT|BPF_X: + case BPF_JMP|BPF_JGE|BPF_X: + case BPF_JMP|BPF_JEQ|BPF_X: + case BPF_JMP|BPF_JSET|BPF_X: + if (pc->code == (BPF_JMP|BPF_JA)) jt = jf = pc->k; - break; - case BPF_JEQ: - case BPF_JGT: - case BPF_JGE: - case BPF_JSET: + else { jt = pc->jt; jf = pc->jf; - break; - default: - goto fail; } negate = (jt == 0) ? 1 : 0; @@ -1617,79 +1551,54 @@ bpfjit_generate_code(struct bpf_insn *in BPFJIT_ASSERT(jtf[branching].bj_jump == NULL); jtf[branching].bj_jump = jump; } + break; - continue; - - case BPF_RET: - - rval = BPF_RVAL(pc->code); - if (rval == BPF_X) - goto fail; - - /* BPF_RET+BPF_K accept k bytes */ - if (rval == BPF_K) { - status = sljit_emit_op1(compiler, - SLJIT_MOV, - BPFJIT_A, 0, - SLJIT_IMM, (uint32_t)pc->k); - if (status != SLJIT_SUCCESS) - goto fail; - } + case BPF_RET|BPF_K: + status = sljit_emit_op1(compiler, + SLJIT_MOV, + BPFJIT_A, 0, + SLJIT_IMM, (uint32_t)pc->k); + break; - /* BPF_RET+BPF_A accept A bytes */ - if (rval == BPF_A) { + case BPF_RET|BPF_A: #if BPFJIT_A != SLJIT_RETURN_REG - status = sljit_emit_op1(compiler, - SLJIT_MOV, - SLJIT_RETURN_REG, 0, - BPFJIT_A, 0); - if (status != SLJIT_SUCCESS) - goto fail; + status = sljit_emit_op1(compiler, + SLJIT_MOV, + SLJIT_RETURN_REG, 0, + BPFJIT_A, 0); #endif - } - - /* - * Save a jump to a normal return. If the program - * ends with BPF_RET, no jump is needed because - * the normal return is generated right after the - * last instruction. - */ - if (i != insn_count - 1) { - jump = sljit_emit_jump(compiler, SLJIT_JUMP); - if (jump == NULL) - goto fail; - returns[returns_size++] = jump; - } - - continue; - - case BPF_MISC: - - if (pc->code == (BPF_MISC|BPF_TAX)) { - status = sljit_emit_op1(compiler, - SLJIT_MOV_UI, - BPFJIT_X, 0, - BPFJIT_A, 0); - if (status != SLJIT_SUCCESS) - goto fail; - - continue; - } - - if (pc->code == (BPF_MISC|BPF_TXA)) { - status = sljit_emit_op1(compiler, - SLJIT_MOV, - BPFJIT_A, 0, - BPFJIT_X, 0); - if (status != SLJIT_SUCCESS) - goto fail; + break; - continue; - } + case BPF_MISC|BPF_TAX: + status = sljit_emit_op1(compiler, + SLJIT_MOV_UI, + BPFJIT_X, 0, + BPFJIT_A, 0); + break; + case BPF_MISC|BPF_TXA: + status = sljit_emit_op1(compiler, + SLJIT_MOV, + BPFJIT_A, 0, + BPFJIT_X, 0); + break; + } + if (status != SLJIT_SUCCESS) goto fail; - } /* switch */ - } /* main loop */ + + /* + * Save a jump to a normal return. If the program + * ends with BPF_RET, no jump is needed because + * the normal return is generated right after the + * last instruction. + */ + if (BPF_CLASS(pc->code) == BPF_RET && i != insn_count - 1) { + jump = sljit_emit_jump(compiler, SLJIT_JUMP); + if (jump == NULL) + goto fail; + returns[returns_size++] = jump; + } + } BPFJIT_ASSERT(ret0_size == ret0_maxsize); BPFJIT_ASSERT(returns_size <= returns_maxsize);