Commit 3e2a33cf authored by Jiong Wang's avatar Jiong Wang Committed by Alexei Starovoitov

sparc: bpf: eliminate zero extension code-gen

Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: default avatarJiong Wang <jiong.wang@netronome.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 591006b9
...@@ -908,6 +908,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) ...@@ -908,6 +908,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
/* dst = src */ /* dst = src */
case BPF_ALU | BPF_MOV | BPF_X: case BPF_ALU | BPF_MOV | BPF_X:
emit_alu3_K(SRL, src, 0, dst, ctx); emit_alu3_K(SRL, src, 0, dst, ctx);
if (insn_is_zext(&insn[1]))
return 1;
break; break;
case BPF_ALU64 | BPF_MOV | BPF_X: case BPF_ALU64 | BPF_MOV | BPF_X:
emit_reg_move(src, dst, ctx); emit_reg_move(src, dst, ctx);
...@@ -942,6 +944,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) ...@@ -942,6 +944,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
case BPF_ALU | BPF_DIV | BPF_X: case BPF_ALU | BPF_DIV | BPF_X:
emit_write_y(G0, ctx); emit_write_y(G0, ctx);
emit_alu(DIV, src, dst, ctx); emit_alu(DIV, src, dst, ctx);
if (insn_is_zext(&insn[1]))
return 1;
break; break;
case BPF_ALU64 | BPF_DIV | BPF_X: case BPF_ALU64 | BPF_DIV | BPF_X:
emit_alu(UDIVX, src, dst, ctx); emit_alu(UDIVX, src, dst, ctx);
...@@ -975,6 +979,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) ...@@ -975,6 +979,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
break; break;
case BPF_ALU | BPF_RSH | BPF_X: case BPF_ALU | BPF_RSH | BPF_X:
emit_alu(SRL, src, dst, ctx); emit_alu(SRL, src, dst, ctx);
if (insn_is_zext(&insn[1]))
return 1;
break; break;
case BPF_ALU64 | BPF_RSH | BPF_X: case BPF_ALU64 | BPF_RSH | BPF_X:
emit_alu(SRLX, src, dst, ctx); emit_alu(SRLX, src, dst, ctx);
...@@ -997,9 +1003,12 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) ...@@ -997,9 +1003,12 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
case 16: case 16:
emit_alu_K(SLL, dst, 16, ctx); emit_alu_K(SLL, dst, 16, ctx);
emit_alu_K(SRL, dst, 16, ctx); emit_alu_K(SRL, dst, 16, ctx);
if (insn_is_zext(&insn[1]))
return 1;
break; break;
case 32: case 32:
emit_alu_K(SRL, dst, 0, ctx); if (!ctx->prog->aux->verifier_zext)
emit_alu_K(SRL, dst, 0, ctx);
break; break;
case 64: case 64:
/* nop */ /* nop */
...@@ -1021,6 +1030,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) ...@@ -1021,6 +1030,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
emit_alu3_K(AND, dst, 0xff, dst, ctx); emit_alu3_K(AND, dst, 0xff, dst, ctx);
emit_alu3_K(SLL, tmp, 8, tmp, ctx); emit_alu3_K(SLL, tmp, 8, tmp, ctx);
emit_alu(OR, tmp, dst, ctx); emit_alu(OR, tmp, dst, ctx);
if (insn_is_zext(&insn[1]))
return 1;
break; break;
case 32: case 32:
...@@ -1037,6 +1048,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) ...@@ -1037,6 +1048,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
emit_alu3_K(AND, dst, 0xff, dst, ctx); /* dst = dst & 0xff */ emit_alu3_K(AND, dst, 0xff, dst, ctx); /* dst = dst & 0xff */
emit_alu3_K(SLL, dst, 24, dst, ctx); /* dst = dst << 24 */ emit_alu3_K(SLL, dst, 24, dst, ctx); /* dst = dst << 24 */
emit_alu(OR, tmp, dst, ctx); /* dst = dst | tmp */ emit_alu(OR, tmp, dst, ctx); /* dst = dst | tmp */
if (insn_is_zext(&insn[1]))
return 1;
break; break;
case 64: case 64:
...@@ -1050,6 +1063,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) ...@@ -1050,6 +1063,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
/* dst = imm */ /* dst = imm */
case BPF_ALU | BPF_MOV | BPF_K: case BPF_ALU | BPF_MOV | BPF_K:
emit_loadimm32(imm, dst, ctx); emit_loadimm32(imm, dst, ctx);
if (insn_is_zext(&insn[1]))
return 1;
break; break;
case BPF_ALU64 | BPF_MOV | BPF_K: case BPF_ALU64 | BPF_MOV | BPF_K:
emit_loadimm_sext(imm, dst, ctx); emit_loadimm_sext(imm, dst, ctx);
...@@ -1132,6 +1147,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) ...@@ -1132,6 +1147,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
break; break;
case BPF_ALU | BPF_RSH | BPF_K: case BPF_ALU | BPF_RSH | BPF_K:
emit_alu_K(SRL, dst, imm, ctx); emit_alu_K(SRL, dst, imm, ctx);
if (insn_is_zext(&insn[1]))
return 1;
break; break;
case BPF_ALU64 | BPF_RSH | BPF_K: case BPF_ALU64 | BPF_RSH | BPF_K:
emit_alu_K(SRLX, dst, imm, ctx); emit_alu_K(SRLX, dst, imm, ctx);
...@@ -1144,7 +1161,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) ...@@ -1144,7 +1161,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
break; break;
do_alu32_trunc: do_alu32_trunc:
if (BPF_CLASS(code) == BPF_ALU) if (BPF_CLASS(code) == BPF_ALU &&
!ctx->prog->aux->verifier_zext)
emit_alu_K(SRL, dst, 0, ctx); emit_alu_K(SRL, dst, 0, ctx);
break; break;
...@@ -1265,6 +1283,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) ...@@ -1265,6 +1283,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
rs2 = RS2(tmp); rs2 = RS2(tmp);
} }
emit(opcode | RS1(src) | rs2 | RD(dst), ctx); emit(opcode | RS1(src) | rs2 | RD(dst), ctx);
if (opcode != LD64 && insn_is_zext(&insn[1]))
return 1;
break; break;
} }
/* ST: *(size *)(dst + off) = imm */ /* ST: *(size *)(dst + off) = imm */
...@@ -1432,6 +1452,11 @@ static void jit_fill_hole(void *area, unsigned int size) ...@@ -1432,6 +1452,11 @@ static void jit_fill_hole(void *area, unsigned int size)
*ptr++ = 0x91d02005; /* ta 5 */ *ptr++ = 0x91d02005; /* ta 5 */
} }
bool bpf_jit_needs_zext(void)
{
return true;
}
struct sparc64_jit_data { struct sparc64_jit_data {
struct bpf_binary_header *header; struct bpf_binary_header *header;
u8 *image; u8 *image;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment