]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
nfp: bpf: tabularize generations of compare operations
authorJakub Kicinski <jakub.kicinski@netronome.com>
Wed, 25 Apr 2018 04:22:38 +0000 (21:22 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Wed, 25 Apr 2018 07:56:10 +0000 (09:56 +0200)
There are quite a few compare instructions now, use a table
to translate BPF instruction code to NFP instruction parameters
instead of parameterizing helpers.  This saves LOC and makes
future extensions easier.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
drivers/net/ethernet/netronome/nfp/bpf/jit.c

index a5590988fc699e9c20c92dbd75e04523be1ee0d2..5b8da7a67df46757fbf00178307b7beb5c039299 100644 (file)
@@ -1214,45 +1214,79 @@ wrp_test_reg(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
        return 0;
 }
 
-static int
-wrp_cmp_imm(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
-           enum br_mask br_mask, bool swap)
+static const struct jmp_code_map {
+       enum br_mask br_mask;
+       bool swap;
+} jmp_code_map[] = {
+       [BPF_JGT >> 4]  = { BR_BLO, true },
+       [BPF_JGE >> 4]  = { BR_BHS, false },
+       [BPF_JLT >> 4]  = { BR_BLO, false },
+       [BPF_JLE >> 4]  = { BR_BHS, true },
+       [BPF_JSGT >> 4] = { BR_BLT, true },
+       [BPF_JSGE >> 4] = { BR_BGE, false },
+       [BPF_JSLT >> 4] = { BR_BLT, false },
+       [BPF_JSLE >> 4] = { BR_BGE, true },
+};
+
+static const struct jmp_code_map *nfp_jmp_code_get(struct nfp_insn_meta *meta)
+{
+       unsigned int op;
+
+       op = BPF_OP(meta->insn.code) >> 4;
+       /* br_mask of 0 is BR_BEQ which we don't use in jump code table */
+       if (WARN_ONCE(op >= ARRAY_SIZE(jmp_code_map) ||
+                     !jmp_code_map[op].br_mask,
+                     "no code found for jump instruction"))
+               return NULL;
+
+       return &jmp_code_map[op];
+}
+
+static int cmp_imm(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
 {
        const struct bpf_insn *insn = &meta->insn;
        u64 imm = insn->imm; /* sign extend */
+       const struct jmp_code_map *code;
        u8 reg = insn->dst_reg * 2;
        swreg tmp_reg;
 
+       code = nfp_jmp_code_get(meta);
+       if (!code)
+               return -EINVAL;
+
        tmp_reg = ur_load_imm_any(nfp_prog, imm & ~0U, imm_b(nfp_prog));
-       if (!swap)
+       if (!code->swap)
                emit_alu(nfp_prog, reg_none(), reg_a(reg), ALU_OP_SUB, tmp_reg);
        else
                emit_alu(nfp_prog, reg_none(), tmp_reg, ALU_OP_SUB, reg_a(reg));
 
        tmp_reg = ur_load_imm_any(nfp_prog, imm >> 32, imm_b(nfp_prog));
-       if (!swap)
+       if (!code->swap)
                emit_alu(nfp_prog, reg_none(),
                         reg_a(reg + 1), ALU_OP_SUB_C, tmp_reg);
        else
                emit_alu(nfp_prog, reg_none(),
                         tmp_reg, ALU_OP_SUB_C, reg_a(reg + 1));
 
-       emit_br(nfp_prog, br_mask, insn->off, 0);
+       emit_br(nfp_prog, code->br_mask, insn->off, 0);
 
        return 0;
 }
 
-static int
-wrp_cmp_reg(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
-           enum br_mask br_mask, bool swap)
+static int cmp_reg(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
 {
        const struct bpf_insn *insn = &meta->insn;
+       const struct jmp_code_map *code;
        u8 areg, breg;
 
+       code = nfp_jmp_code_get(meta);
+       if (!code)
+               return -EINVAL;
+
        areg = insn->dst_reg * 2;
        breg = insn->src_reg * 2;
 
-       if (swap) {
+       if (code->swap) {
                areg ^= breg;
                breg ^= areg;
                areg ^= breg;
@@ -1261,7 +1295,7 @@ wrp_cmp_reg(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
        emit_alu(nfp_prog, reg_none(), reg_a(areg), ALU_OP_SUB, reg_b(breg));
        emit_alu(nfp_prog, reg_none(),
                 reg_a(areg + 1), ALU_OP_SUB_C, reg_b(breg + 1));
-       emit_br(nfp_prog, br_mask, insn->off, 0);
+       emit_br(nfp_prog, code->br_mask, insn->off, 0);
 
        return 0;
 }
@@ -2283,46 +2317,6 @@ static int jeq_imm(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
        return 0;
 }
 
-static int jgt_imm(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
-{
-       return wrp_cmp_imm(nfp_prog, meta, BR_BLO, true);
-}
-
-static int jge_imm(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
-{
-       return wrp_cmp_imm(nfp_prog, meta, BR_BHS, false);
-}
-
-static int jlt_imm(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
-{
-       return wrp_cmp_imm(nfp_prog, meta, BR_BLO, false);
-}
-
-static int jle_imm(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
-{
-       return wrp_cmp_imm(nfp_prog, meta, BR_BHS, true);
-}
-
-static int jsgt_imm(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
-{
-       return wrp_cmp_imm(nfp_prog, meta, BR_BLT, true);
-}
-
-static int jsge_imm(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
-{
-       return wrp_cmp_imm(nfp_prog, meta, BR_BGE, false);
-}
-
-static int jslt_imm(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
-{
-       return wrp_cmp_imm(nfp_prog, meta, BR_BLT, false);
-}
-
-static int jsle_imm(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
-{
-       return wrp_cmp_imm(nfp_prog, meta, BR_BGE, true);
-}
-
 static int jset_imm(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
 {
        const struct bpf_insn *insn = &meta->insn;
@@ -2392,46 +2386,6 @@ static int jeq_reg(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
        return 0;
 }
 
-static int jgt_reg(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
-{
-       return wrp_cmp_reg(nfp_prog, meta, BR_BLO, true);
-}
-
-static int jge_reg(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
-{
-       return wrp_cmp_reg(nfp_prog, meta, BR_BHS, false);
-}
-
-static int jlt_reg(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
-{
-       return wrp_cmp_reg(nfp_prog, meta, BR_BLO, false);
-}
-
-static int jle_reg(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
-{
-       return wrp_cmp_reg(nfp_prog, meta, BR_BHS, true);
-}
-
-static int jsgt_reg(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
-{
-       return wrp_cmp_reg(nfp_prog, meta, BR_BLT, true);
-}
-
-static int jsge_reg(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
-{
-       return wrp_cmp_reg(nfp_prog, meta, BR_BGE, false);
-}
-
-static int jslt_reg(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
-{
-       return wrp_cmp_reg(nfp_prog, meta, BR_BLT, false);
-}
-
-static int jsle_reg(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
-{
-       return wrp_cmp_reg(nfp_prog, meta, BR_BGE, true);
-}
-
 static int jset_reg(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
 {
        return wrp_test_reg(nfp_prog, meta, ALU_OP_AND, BR_BNE);
@@ -2520,25 +2474,25 @@ static const instr_cb_t instr_cb[256] = {
        [BPF_ST | BPF_MEM | BPF_DW] =   mem_st8,
        [BPF_JMP | BPF_JA | BPF_K] =    jump,
        [BPF_JMP | BPF_JEQ | BPF_K] =   jeq_imm,
-       [BPF_JMP | BPF_JGT | BPF_K] =   jgt_imm,
-       [BPF_JMP | BPF_JGE | BPF_K] =   jge_imm,
-       [BPF_JMP | BPF_JLT | BPF_K] =   jlt_imm,
-       [BPF_JMP | BPF_JLE | BPF_K] =   jle_imm,
-       [BPF_JMP | BPF_JSGT | BPF_K] =  jsgt_imm,
-       [BPF_JMP | BPF_JSGE | BPF_K] =  jsge_imm,
-       [BPF_JMP | BPF_JSLT | BPF_K] =  jslt_imm,
-       [BPF_JMP | BPF_JSLE | BPF_K] =  jsle_imm,
+       [BPF_JMP | BPF_JGT | BPF_K] =   cmp_imm,
+       [BPF_JMP | BPF_JGE | BPF_K] =   cmp_imm,
+       [BPF_JMP | BPF_JLT | BPF_K] =   cmp_imm,
+       [BPF_JMP | BPF_JLE | BPF_K] =   cmp_imm,
+       [BPF_JMP | BPF_JSGT | BPF_K] =  cmp_imm,
+       [BPF_JMP | BPF_JSGE | BPF_K] =  cmp_imm,
+       [BPF_JMP | BPF_JSLT | BPF_K] =  cmp_imm,
+       [BPF_JMP | BPF_JSLE | BPF_K] =  cmp_imm,
        [BPF_JMP | BPF_JSET | BPF_K] =  jset_imm,
        [BPF_JMP | BPF_JNE | BPF_K] =   jne_imm,
        [BPF_JMP | BPF_JEQ | BPF_X] =   jeq_reg,
-       [BPF_JMP | BPF_JGT | BPF_X] =   jgt_reg,
-       [BPF_JMP | BPF_JGE | BPF_X] =   jge_reg,
-       [BPF_JMP | BPF_JLT | BPF_X] =   jlt_reg,
-       [BPF_JMP | BPF_JLE | BPF_X] =   jle_reg,
-       [BPF_JMP | BPF_JSGT | BPF_X] =  jsgt_reg,
-       [BPF_JMP | BPF_JSGE | BPF_X] =  jsge_reg,
-       [BPF_JMP | BPF_JSLT | BPF_X] =  jslt_reg,
-       [BPF_JMP | BPF_JSLE | BPF_X] =  jsle_reg,
+       [BPF_JMP | BPF_JGT | BPF_X] =   cmp_reg,
+       [BPF_JMP | BPF_JGE | BPF_X] =   cmp_reg,
+       [BPF_JMP | BPF_JLT | BPF_X] =   cmp_reg,
+       [BPF_JMP | BPF_JLE | BPF_X] =   cmp_reg,
+       [BPF_JMP | BPF_JSGT | BPF_X] =  cmp_reg,
+       [BPF_JMP | BPF_JSGE | BPF_X] =  cmp_reg,
+       [BPF_JMP | BPF_JSLT | BPF_X] =  cmp_reg,
+       [BPF_JMP | BPF_JSLE | BPF_X] =  cmp_reg,
        [BPF_JMP | BPF_JSET | BPF_X] =  jset_reg,
        [BPF_JMP | BPF_JNE | BPF_X] =   jne_reg,
        [BPF_JMP | BPF_CALL] =          call,