summaryrefslogtreecommitdiff
path: root/arch/powerpc/net
diff options
context:
space:
mode:
authorChristophe Leroy <christophe.leroy@csgroup.eu>2023-02-01 11:04:31 +0100
committerMichael Ellerman <mpe@ellerman.id.au>2023-02-10 22:17:35 +1100
commit19daf0aef84f33bde9c742ed41b4ded567b8dfbf (patch)
tree25c281c9ee3166d4e0beb2c3a4e7145642dec9d2 /arch/powerpc/net
parentc88da29b4d2ce8d0070646b8f99729e9b355a4bf (diff)
powerpc/bpf/32: perform three operands ALU operations
When an ALU instruction is preceded by a MOV instruction that just moves a source register into the destination register of the ALU, replace that MOV+ALU instructions by an ALU operation taking the source of the MOV as second source instead of using its destination. Before the change, code could look like the following, with superfluous separate register move (mr) instructions. 70: 7f c6 f3 78 mr r6,r30 74: 7f a5 eb 78 mr r5,r29 78: 30 c6 ff f4 addic r6,r6,-12 7c: 7c a5 01 d4 addme r5,r5 With this commit, addition instructions take r30 and r29 directly. 70: 30 de ff f4 addic r6,r30,-12 74: 7c bd 01 d4 addme r5,r29 Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/b6719beaf01f9dcbcdbb787ef67c4a2f8e3a4cb6.1675245773.git.christophe.leroy@csgroup.eu
Diffstat (limited to 'arch/powerpc/net')
-rw-r--r--arch/powerpc/net/bpf_jit_comp32.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/arch/powerpc/net/bpf_jit_comp32.c b/arch/powerpc/net/bpf_jit_comp32.c
index 5d36ff7a0a8b..7f91ea064c08 100644
--- a/arch/powerpc/net/bpf_jit_comp32.c
+++ b/arch/powerpc/net/bpf_jit_comp32.c
@@ -290,6 +290,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
for (i = 0; i < flen; i++) {
u32 code = insn[i].code;
+ u32 prevcode = i ? insn[i - 1].code : 0;
u32 dst_reg = bpf_to_ppc(insn[i].dst_reg);
u32 dst_reg_h = dst_reg - 1;
u32 src_reg = bpf_to_ppc(insn[i].src_reg);
@@ -308,6 +309,15 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
u32 tmp_idx;
int j;
+ if (i && (BPF_CLASS(code) == BPF_ALU64 || BPF_CLASS(code) == BPF_ALU) &&
+ (BPF_CLASS(prevcode) == BPF_ALU64 || BPF_CLASS(prevcode) == BPF_ALU) &&
+ BPF_OP(prevcode) == BPF_MOV && BPF_SRC(prevcode) == BPF_X &&
+ insn[i - 1].dst_reg == insn[i].dst_reg && insn[i - 1].imm != 1) {
+ src2_reg = bpf_to_ppc(insn[i - 1].src_reg);
+ src2_reg_h = src2_reg - 1;
+ ctx->idx = addrs[i - 1] / 4;
+ }
+
/*
* addrs[] maps a BPF bytecode address into a real offset from
* the start of the body code.