bpf: x86: Factor out emission of REX byte
authorBrendan Jackman <jackmanb@google.com>
Thu, 14 Jan 2021 18:17:42 +0000 (18:17 +0000)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 15 Jan 2021 02:34:28 +0000 (18:34 -0800)
The JIT case for encoding atomic ops is about to get more
complicated. In order to make the review & resulting code easier,
let's factor out some shared helpers.

Signed-off-by: Brendan Jackman <jackmanb@google.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Link: https://lore.kernel.org/bpf/20210114181751.768687-3-jackmanb@google.com
arch/x86/net/bpf_jit_comp.c

index 30526776fa78c3feb6e05a622dc3eef7b81a0d4d..f15c93275a18ae9f00b92140eaa896c5b6a2fc0a 100644 (file)
@@ -702,6 +702,21 @@ static void emit_insn_suffix(u8 **pprog, u32 ptr_reg, u32 val_reg, int off)
        *pprog = prog;
 }
 
+/*
+ * Emit a REX byte if it will be necessary to address these registers
+ */
+static void maybe_emit_mod(u8 **pprog, u32 dst_reg, u32 src_reg, bool is64)
+{
+       u8 *prog = *pprog;
+       int cnt = 0;
+
+       if (is64)
+               EMIT1(add_2mod(0x48, dst_reg, src_reg));
+       else if (is_ereg(dst_reg) || is_ereg(src_reg))
+               EMIT1(add_2mod(0x40, dst_reg, src_reg));
+       *pprog = prog;
+}
+
 /* LDX: dst_reg = *(u8*)(src_reg + off) */
 static void emit_ldx(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off)
 {
@@ -854,10 +869,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
                        case BPF_OR: b2 = 0x09; break;
                        case BPF_XOR: b2 = 0x31; break;
                        }
-                       if (BPF_CLASS(insn->code) == BPF_ALU64)
-                               EMIT1(add_2mod(0x48, dst_reg, src_reg));
-                       else if (is_ereg(dst_reg) || is_ereg(src_reg))
-                               EMIT1(add_2mod(0x40, dst_reg, src_reg));
+                       maybe_emit_mod(&prog, dst_reg, src_reg,
+                                      BPF_CLASS(insn->code) == BPF_ALU64);
                        EMIT2(b2, add_2reg(0xC0, dst_reg, src_reg));
                        break;
 
@@ -1302,20 +1315,16 @@ xadd:
                case BPF_JMP32 | BPF_JSGE | BPF_X:
                case BPF_JMP32 | BPF_JSLE | BPF_X:
                        /* cmp dst_reg, src_reg */
-                       if (BPF_CLASS(insn->code) == BPF_JMP)
-                               EMIT1(add_2mod(0x48, dst_reg, src_reg));
-                       else if (is_ereg(dst_reg) || is_ereg(src_reg))
-                               EMIT1(add_2mod(0x40, dst_reg, src_reg));
+                       maybe_emit_mod(&prog, dst_reg, src_reg,
+                                      BPF_CLASS(insn->code) == BPF_JMP);
                        EMIT2(0x39, add_2reg(0xC0, dst_reg, src_reg));
                        goto emit_cond_jmp;
 
                case BPF_JMP | BPF_JSET | BPF_X:
                case BPF_JMP32 | BPF_JSET | BPF_X:
                        /* test dst_reg, src_reg */
-                       if (BPF_CLASS(insn->code) == BPF_JMP)
-                               EMIT1(add_2mod(0x48, dst_reg, src_reg));
-                       else if (is_ereg(dst_reg) || is_ereg(src_reg))
-                               EMIT1(add_2mod(0x40, dst_reg, src_reg));
+                       maybe_emit_mod(&prog, dst_reg, src_reg,
+                                      BPF_CLASS(insn->code) == BPF_JMP);
                        EMIT2(0x85, add_2reg(0xC0, dst_reg, src_reg));
                        goto emit_cond_jmp;
 
@@ -1351,10 +1360,8 @@ xadd:
                case BPF_JMP32 | BPF_JSLE | BPF_K:
                        /* test dst_reg, dst_reg to save one extra byte */
                        if (imm32 == 0) {
-                               if (BPF_CLASS(insn->code) == BPF_JMP)
-                                       EMIT1(add_2mod(0x48, dst_reg, dst_reg));
-                               else if (is_ereg(dst_reg))
-                                       EMIT1(add_2mod(0x40, dst_reg, dst_reg));
+                               maybe_emit_mod(&prog, dst_reg, dst_reg,
+                                              BPF_CLASS(insn->code) == BPF_JMP);
                                EMIT2(0x85, add_2reg(0xC0, dst_reg, dst_reg));
                                goto emit_cond_jmp;
                        }