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: Jiong Wang <jiong.wang@netronome.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
163541e6ba
commit
a4c927733e
|
@ -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,
|
||||||
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,
|
||||||
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,
|
||||||
*/
|
*/
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
/* 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 {
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue