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: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
2e4a30983b
commit
de0a444dda
@ -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,
|
|||||||
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user