Commit a4c92773 authored by Jiong Wang's avatar Jiong Wang Committed by Alexei Starovoitov

powerpc: bpf: eliminate zero extension code-gen

Cc: Naveen N. Rao <naveen.n.rao@linux.ibm.com>
Cc: Sandipan Das <sandipan@linux.ibm.com>
Signed-off-by: default avatarJiong Wang <jiong.wang@netronome.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 163541e6
...@@ -504,6 +504,9 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, ...@@ -504,6 +504,9 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
case BPF_ALU | BPF_LSH | BPF_X: /* (u32) dst <<= (u32) src */ case BPF_ALU | BPF_LSH | BPF_X: /* (u32) dst <<= (u32) src */
/* slw clears top 32 bits */ /* slw clears top 32 bits */
PPC_SLW(dst_reg, dst_reg, src_reg); PPC_SLW(dst_reg, dst_reg, src_reg);
/* skip zero extension move, but set address map. */
if (insn_is_zext(&insn[i + 1]))
addrs[++i] = ctx->idx * 4;
break; break;
case BPF_ALU64 | BPF_LSH | BPF_X: /* dst <<= src; */ case BPF_ALU64 | BPF_LSH | BPF_X: /* dst <<= src; */
PPC_SLD(dst_reg, dst_reg, src_reg); PPC_SLD(dst_reg, dst_reg, src_reg);
...@@ -511,6 +514,8 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, ...@@ -511,6 +514,8 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
case BPF_ALU | BPF_LSH | BPF_K: /* (u32) dst <<== (u32) imm */ case BPF_ALU | BPF_LSH | BPF_K: /* (u32) dst <<== (u32) imm */
/* with imm 0, we still need to clear top 32 bits */ /* with imm 0, we still need to clear top 32 bits */
PPC_SLWI(dst_reg, dst_reg, imm); PPC_SLWI(dst_reg, dst_reg, imm);
if (insn_is_zext(&insn[i + 1]))
addrs[++i] = ctx->idx * 4;
break; break;
case BPF_ALU64 | BPF_LSH | BPF_K: /* dst <<== imm */ case BPF_ALU64 | BPF_LSH | BPF_K: /* dst <<== imm */
if (imm != 0) if (imm != 0)
...@@ -518,12 +523,16 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, ...@@ -518,12 +523,16 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
break; break;
case BPF_ALU | BPF_RSH | BPF_X: /* (u32) dst >>= (u32) src */ case BPF_ALU | BPF_RSH | BPF_X: /* (u32) dst >>= (u32) src */
PPC_SRW(dst_reg, dst_reg, src_reg); PPC_SRW(dst_reg, dst_reg, src_reg);
if (insn_is_zext(&insn[i + 1]))
addrs[++i] = ctx->idx * 4;
break; break;
case BPF_ALU64 | BPF_RSH | BPF_X: /* dst >>= src */ case BPF_ALU64 | BPF_RSH | BPF_X: /* dst >>= src */
PPC_SRD(dst_reg, dst_reg, src_reg); PPC_SRD(dst_reg, dst_reg, src_reg);
break; break;
case BPF_ALU | BPF_RSH | BPF_K: /* (u32) dst >>= (u32) imm */ case BPF_ALU | BPF_RSH | BPF_K: /* (u32) dst >>= (u32) imm */
PPC_SRWI(dst_reg, dst_reg, imm); PPC_SRWI(dst_reg, dst_reg, imm);
if (insn_is_zext(&insn[i + 1]))
addrs[++i] = ctx->idx * 4;
break; break;
case BPF_ALU64 | BPF_RSH | BPF_K: /* dst >>= imm */ case BPF_ALU64 | BPF_RSH | BPF_K: /* dst >>= imm */
if (imm != 0) if (imm != 0)
...@@ -548,6 +557,11 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, ...@@ -548,6 +557,11 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
*/ */
case BPF_ALU | BPF_MOV | BPF_X: /* (u32) dst = src */ case BPF_ALU | BPF_MOV | BPF_X: /* (u32) dst = src */
case BPF_ALU64 | BPF_MOV | BPF_X: /* dst = src */ case BPF_ALU64 | BPF_MOV | BPF_X: /* dst = src */
if (imm == 1) {
/* special mov32 for zext */
PPC_RLWINM(dst_reg, dst_reg, 0, 0, 31);
break;
}
PPC_MR(dst_reg, src_reg); PPC_MR(dst_reg, src_reg);
goto bpf_alu32_trunc; goto bpf_alu32_trunc;
case BPF_ALU | BPF_MOV | BPF_K: /* (u32) dst = imm */ case BPF_ALU | BPF_MOV | BPF_K: /* (u32) dst = imm */
...@@ -555,11 +569,13 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, ...@@ -555,11 +569,13 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
PPC_LI32(dst_reg, imm); PPC_LI32(dst_reg, imm);
if (imm < 0) if (imm < 0)
goto bpf_alu32_trunc; goto bpf_alu32_trunc;
else if (insn_is_zext(&insn[i + 1]))
addrs[++i] = ctx->idx * 4;
break; break;
bpf_alu32_trunc: bpf_alu32_trunc:
/* Truncate to 32-bits */ /* Truncate to 32-bits */
if (BPF_CLASS(code) == BPF_ALU) if (BPF_CLASS(code) == BPF_ALU && !fp->aux->verifier_zext)
PPC_RLWINM(dst_reg, dst_reg, 0, 0, 31); PPC_RLWINM(dst_reg, dst_reg, 0, 0, 31);
break; break;
...@@ -618,10 +634,13 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, ...@@ -618,10 +634,13 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
case 16: case 16:
/* zero-extend 16 bits into 64 bits */ /* zero-extend 16 bits into 64 bits */
PPC_RLDICL(dst_reg, dst_reg, 0, 48); PPC_RLDICL(dst_reg, dst_reg, 0, 48);
if (insn_is_zext(&insn[i + 1]))
addrs[++i] = ctx->idx * 4;
break; break;
case 32: case 32:
/* zero-extend 32 bits into 64 bits */ if (!fp->aux->verifier_zext)
PPC_RLDICL(dst_reg, dst_reg, 0, 32); /* zero-extend 32 bits into 64 bits */
PPC_RLDICL(dst_reg, dst_reg, 0, 32);
break; break;
case 64: case 64:
/* nop */ /* nop */
...@@ -698,14 +717,20 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, ...@@ -698,14 +717,20 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
/* dst = *(u8 *)(ul) (src + off) */ /* dst = *(u8 *)(ul) (src + off) */
case BPF_LDX | BPF_MEM | BPF_B: case BPF_LDX | BPF_MEM | BPF_B:
PPC_LBZ(dst_reg, src_reg, off); PPC_LBZ(dst_reg, src_reg, off);
if (insn_is_zext(&insn[i + 1]))
addrs[++i] = ctx->idx * 4;
break; break;
/* dst = *(u16 *)(ul) (src + off) */ /* dst = *(u16 *)(ul) (src + off) */
case BPF_LDX | BPF_MEM | BPF_H: case BPF_LDX | BPF_MEM | BPF_H:
PPC_LHZ(dst_reg, src_reg, off); PPC_LHZ(dst_reg, src_reg, off);
if (insn_is_zext(&insn[i + 1]))
addrs[++i] = ctx->idx * 4;
break; break;
/* dst = *(u32 *)(ul) (src + off) */ /* dst = *(u32 *)(ul) (src + off) */
case BPF_LDX | BPF_MEM | BPF_W: case BPF_LDX | BPF_MEM | BPF_W:
PPC_LWZ(dst_reg, src_reg, off); PPC_LWZ(dst_reg, src_reg, off);
if (insn_is_zext(&insn[i + 1]))
addrs[++i] = ctx->idx * 4;
break; break;
/* dst = *(u64 *)(ul) (src + off) */ /* dst = *(u64 *)(ul) (src + off) */
case BPF_LDX | BPF_MEM | BPF_DW: case BPF_LDX | BPF_MEM | BPF_DW:
...@@ -1046,6 +1071,11 @@ struct powerpc64_jit_data { ...@@ -1046,6 +1071,11 @@ struct powerpc64_jit_data {
struct codegen_context ctx; struct codegen_context ctx;
}; };
bool bpf_jit_needs_zext(void)
{
return true;
}
struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
{ {
u32 proglen; u32 proglen;
......
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