Commit de0a444d authored by Daniel Borkmann's avatar Daniel Borkmann Committed by Alexei Starovoitov

bpf, x86: small optimization in alu ops with imm

For the BPF_REG_0 (BPF_REG_A in cBPF, respectively), we can use
the short form of the opcode as dst mapping is on eax/rax and
thus save a byte per such operation. Added to add/sub/and/or/xor
for 32/64 bit when K immediate is used. There may be more such
low-hanging fruit to add in future as well.
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Acked-by: default avatarAlexei Starovoitov <ast@kernel.org>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 2e4a3098
...@@ -152,6 +152,11 @@ static bool is_ereg(u32 reg) ...@@ -152,6 +152,11 @@ static bool is_ereg(u32 reg)
BIT(BPF_REG_AX)); BIT(BPF_REG_AX));
} }
static bool is_axreg(u32 reg)
{
return reg == BPF_REG_0;
}
/* add modifiers if 'reg' maps to x64 registers r8..r15 */ /* add modifiers if 'reg' maps to x64 registers r8..r15 */
static u8 add_1mod(u8 byte, u32 reg) static u8 add_1mod(u8 byte, u32 reg)
{ {
...@@ -445,16 +450,36 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, ...@@ -445,16 +450,36 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
else if (is_ereg(dst_reg)) else if (is_ereg(dst_reg))
EMIT1(add_1mod(0x40, dst_reg)); EMIT1(add_1mod(0x40, dst_reg));
/* b3 holds 'normal' opcode, b2 short form only valid
* in case dst is eax/rax.
*/
switch (BPF_OP(insn->code)) { switch (BPF_OP(insn->code)) {
case BPF_ADD: b3 = 0xC0; break; case BPF_ADD:
case BPF_SUB: b3 = 0xE8; break; b3 = 0xC0;
case BPF_AND: b3 = 0xE0; break; b2 = 0x05;
case BPF_OR: b3 = 0xC8; break; break;
case BPF_XOR: b3 = 0xF0; break; case BPF_SUB:
b3 = 0xE8;
b2 = 0x2D;
break;
case BPF_AND:
b3 = 0xE0;
b2 = 0x25;
break;
case BPF_OR:
b3 = 0xC8;
b2 = 0x0D;
break;
case BPF_XOR:
b3 = 0xF0;
b2 = 0x35;
break;
} }
if (is_imm8(imm32)) if (is_imm8(imm32))
EMIT3(0x83, add_1reg(b3, dst_reg), imm32); EMIT3(0x83, add_1reg(b3, dst_reg), imm32);
else if (is_axreg(dst_reg))
EMIT1_off32(b2, imm32);
else else
EMIT2_off32(0x81, add_1reg(b3, dst_reg), imm32); EMIT2_off32(0x81, add_1reg(b3, dst_reg), imm32);
break; break;
......
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