aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2018-01-19 19:24:35 -0500
committerAlexei Starovoitov <ast@kernel.org>2018-01-19 21:37:00 -0500
commitde0a444ddae61b77683c27cd390e518e33858d20 (patch)
treeb2bb3ce980577d8736bd0174aefa53b5655bf74e
parent2e4a30983b0f9b19b59e38bbf7427d7fdd480d98 (diff)
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>
-rw-r--r--arch/x86/net/bpf_jit_comp.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index b881a979efe1..5acee5139e28 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -152,6 +152,11 @@ static bool is_ereg(u32 reg)
152 BIT(BPF_REG_AX)); 152 BIT(BPF_REG_AX));
153} 153}
154 154
155static bool is_axreg(u32 reg)
156{
157 return reg == BPF_REG_0;
158}
159
155/* add modifiers if 'reg' maps to x64 registers r8..r15 */ 160/* add modifiers if 'reg' maps to x64 registers r8..r15 */
156static u8 add_1mod(u8 byte, u32 reg) 161static u8 add_1mod(u8 byte, u32 reg)
157{ 162{
@@ -445,16 +450,36 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
445 else if (is_ereg(dst_reg)) 450 else if (is_ereg(dst_reg))
446 EMIT1(add_1mod(0x40, dst_reg)); 451 EMIT1(add_1mod(0x40, dst_reg));
447 452
453 /* b3 holds 'normal' opcode, b2 short form only valid
454 * in case dst is eax/rax.
455 */
448 switch (BPF_OP(insn->code)) { 456 switch (BPF_OP(insn->code)) {
449 case BPF_ADD: b3 = 0xC0; break; 457 case BPF_ADD:
450 case BPF_SUB: b3 = 0xE8; break; 458 b3 = 0xC0;
451 case BPF_AND: b3 = 0xE0; break; 459 b2 = 0x05;
452 case BPF_OR: b3 = 0xC8; break; 460 break;
453 case BPF_XOR: b3 = 0xF0; break; 461 case BPF_SUB:
462 b3 = 0xE8;
463 b2 = 0x2D;
464 break;
465 case BPF_AND:
466 b3 = 0xE0;
467 b2 = 0x25;
468 break;
469 case BPF_OR:
470 b3 = 0xC8;
471 b2 = 0x0D;
472 break;
473 case BPF_XOR:
474 b3 = 0xF0;
475 b2 = 0x35;
476 break;
454 } 477 }
455 478
456 if (is_imm8(imm32)) 479 if (is_imm8(imm32))
457 EMIT3(0x83, add_1reg(b3, dst_reg), imm32); 480 EMIT3(0x83, add_1reg(b3, dst_reg), imm32);
481 else if (is_axreg(dst_reg))
482 EMIT1_off32(b2, imm32);
458 else 483 else
459 EMIT2_off32(0x81, add_1reg(b3, dst_reg), imm32); 484 EMIT2_off32(0x81, add_1reg(b3, dst_reg), imm32);
460 break; 485 break;