Simplify multiplications and divisions with constants when the
constant is 1 or -1.

When the constant is a power of 2, replace them by bit shits.

Signed-off-by: Christophe Leroy <christophe.le...@csgroup.eu>
---
 arch/powerpc/net/bpf_jit_comp32.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/net/bpf_jit_comp32.c 
b/arch/powerpc/net/bpf_jit_comp32.c
index c3bc20b91cdc..b1d6ed4d8270 100644
--- a/arch/powerpc/net/bpf_jit_comp32.c
+++ b/arch/powerpc/net/bpf_jit_comp32.c
@@ -391,7 +391,13 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, 
struct codegen_context *
                        EMIT(PPC_RAW_MULW(dst_reg, dst_reg, src_reg));
                        break;
                case BPF_ALU | BPF_MUL | BPF_K: /* (u32) dst *= (u32) imm */
-                       if (imm >= -32768 && imm < 32768) {
+                       if (imm == 1)
+                               break;
+                       if (imm == -1) {
+                               EMIT(PPC_RAW_SUBFIC(dst_reg, dst_reg, 0));
+                       } else if (is_power_of_2((u32)imm)) {
+                               EMIT(PPC_RAW_SLWI(dst_reg, dst_reg, 
ilog2(imm)));
+                       } else if (imm >= -32768 && imm < 32768) {
                                EMIT(PPC_RAW_MULI(dst_reg, dst_reg, imm));
                        } else {
                                PPC_LI32(_R0, imm);
@@ -411,6 +417,13 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, 
struct codegen_context *
                                EMIT(PPC_RAW_SUBFZE(dst_reg_h, dst_reg_h));
                                break;
                        }
+                       if (imm > 0 && is_power_of_2(imm)) {
+                               imm = ilog2(imm);
+                               EMIT(PPC_RAW_RLWINM(dst_reg_h, dst_reg_h, imm, 
0, 31 - imm));
+                               EMIT(PPC_RAW_RLWIMI(dst_reg_h, dst_reg, imm, 32 
- imm, 31));
+                               EMIT(PPC_RAW_SLWI(dst_reg, dst_reg, imm));
+                               break;
+                       }
                        bpf_set_seen_register(ctx, tmp_reg);
                        PPC_LI32(tmp_reg, imm);
                        EMIT(PPC_RAW_MULW(dst_reg_h, dst_reg_h, tmp_reg));
@@ -438,8 +451,12 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, 
struct codegen_context *
                        if (imm == 1)
                                break;
 
-                       PPC_LI32(_R0, imm);
-                       EMIT(PPC_RAW_DIVWU(dst_reg, dst_reg, _R0));
+                       if (is_power_of_2((u32)imm)) {
+                               EMIT(PPC_RAW_SRWI(dst_reg, dst_reg, 
ilog2(imm)));
+                       } else {
+                               PPC_LI32(_R0, imm);
+                               EMIT(PPC_RAW_DIVWU(dst_reg, dst_reg, _R0));
+                       }
                        break;
                case BPF_ALU | BPF_MOD | BPF_K: /* (u32) dst %= (u32) imm */
                        if (!imm)
-- 
2.39.1

Reply via email to