mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
Merge branch 'bpf-mips-add-bpf_movsx-support-to-the-jits'
Nicholas Dudar says: ==================== bpf, mips: Add BPF_MOVSX support to the JITs Add the five MOVSX forms to the MIPS32 and MIPS64 JITs, which currently emit them as ordinary moves. Patch 1 factors register moves into helpers; patch 2 adds sign extension. Use seb/seh on MIPS32 R2+ and doubleword shift pairs on MIPS64, where normalizing the source for seb/seh would eliminate the instruction saving. The MIPS64 sequence also matches GCC's generic lowering [1]. This series depends on SDIV/SMOD v4, whose uasm patch adds seb/seh. This is missing JIT support rather than a regression, hence bpf-next and no Fixes tag. Tested the SDIV/SMOD v4 prerequisite and this series with test_bpf under QEMU Malta on little-endian MIPS32 R1/R2/R6 and MIPS64 R2/R6. All five MOVSX cases went from failure to JIT pass; all 16 signed DIV/MOD cases passed on both revisions. Patched pass/fail totals were: MIPS32 R2/R6: 1050/12 MIPS64 R2/R6: 1049/12 MIPS32 R1: 1045/17 The 12 failures are 8 BSWAP, 3 MEMSX and 1 JMP32_JA. R1's 5 additional failures also occurred on the prerequisite-only baseline. No other test outcome changed between the two revisions. Earlier v2 tests covered both endians and verifier zero-extension handling. No physical hardware was tested. Changes in v3: - Use seb/seh on MIPS32 R2+; retain shift pairs on MIPS64. - Share the 8/16-bit sign-extension sequence within each backend. - Apply on top of SDIV/SMOD v4 for the new uasm emitters. SDIV/SMOD v4: https://lore.kernel.org/bpf/20260911213340.3767930-1-main.kalliope@gmail.com/ v2: https://lore.kernel.org/bpf/20260904111731.673341-1-main.kalliope@gmail.com/ Review: https://lore.kernel.org/bpf/CAM1=_QTN3JJ6jtckf32F8wxBzLDbHSrzUttyMBWNqZKmRe=2rg@mail.gmail.com/ [1] https://github.com/gcc-mirror/gcc/blob/releases/gcc-15.2.0/gcc/config/mips/mips.md#L3921 ==================== Link: https://patch.msgid.link/20260912041220.444715-1-main.kalliope@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
commit
94809ecf9d
|
|
@ -190,6 +190,69 @@ static void emit_zext_ver(struct jit_context *ctx, const u8 dst[])
|
|||
}
|
||||
}
|
||||
|
||||
/* Sign-extend an 8- or 16-bit field into a native register. */
|
||||
static void emit_movsx_r(struct jit_context *ctx, u8 dst, u8 src, s16 off)
|
||||
{
|
||||
int shift;
|
||||
|
||||
if (cpu_has_mips32r2 || cpu_has_mips32r6) {
|
||||
if (off == 8)
|
||||
emit(ctx, seb, dst, src);
|
||||
else
|
||||
emit(ctx, seh, dst, src);
|
||||
} else {
|
||||
shift = 32 - off;
|
||||
emit(ctx, sll, dst, src, shift);
|
||||
emit(ctx, sra, dst, dst, shift);
|
||||
}
|
||||
}
|
||||
|
||||
/* Register move operation (32-bit), optionally with sign extension */
|
||||
static void emit_mov_r32(struct jit_context *ctx, const u8 dst[],
|
||||
const u8 src[], s16 off)
|
||||
{
|
||||
switch (off) {
|
||||
case 8:
|
||||
case 16:
|
||||
emit_movsx_r(ctx, lo(dst), lo(src), off);
|
||||
break;
|
||||
default:
|
||||
/* off == 0 is MOV; the verifier rejects other offsets. */
|
||||
emit_mov_r(ctx, lo(dst), lo(src));
|
||||
break;
|
||||
}
|
||||
clobber_reg(ctx, lo(dst));
|
||||
emit_zext_ver(ctx, dst);
|
||||
}
|
||||
|
||||
/* Register move operation (64-bit), optionally with sign extension */
|
||||
static void emit_mov_r64(struct jit_context *ctx, const u8 dst[],
|
||||
const u8 src[], s16 off)
|
||||
{
|
||||
switch (off) {
|
||||
case 8:
|
||||
case 16:
|
||||
emit_movsx_r(ctx, lo(dst), lo(src), off);
|
||||
emit(ctx, sra, hi(dst), lo(dst), 31);
|
||||
break;
|
||||
case 32:
|
||||
emit(ctx, move, lo(dst), lo(src));
|
||||
emit(ctx, sra, hi(dst), lo(dst), 31);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* off == 0 is ordinary MOV. The verifier rejects other
|
||||
* offsets; defined exceptions require
|
||||
* bpf_jit_supports_percpu_insn() or bpf_jit_supports_arena(),
|
||||
* neither implemented by MIPS.
|
||||
*/
|
||||
emit_mov_r(ctx, lo(dst), lo(src));
|
||||
emit_mov_r(ctx, hi(dst), hi(src));
|
||||
break;
|
||||
}
|
||||
clobber_reg64(ctx, dst);
|
||||
}
|
||||
|
||||
/* Load delay slot, if ISA mandates it */
|
||||
static void emit_load_delay(struct jit_context *ctx)
|
||||
{
|
||||
|
|
@ -1494,8 +1557,7 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)
|
|||
/* Special mov32 for zext */
|
||||
emit_mov_i(ctx, hi(dst), 0);
|
||||
} else {
|
||||
emit_mov_r(ctx, lo(dst), lo(src));
|
||||
emit_zext_ver(ctx, dst);
|
||||
emit_mov_r32(ctx, dst, src, off);
|
||||
}
|
||||
break;
|
||||
/* dst = -dst */
|
||||
|
|
@ -1564,8 +1626,7 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)
|
|||
break;
|
||||
/* dst = src (64-bit) */
|
||||
case BPF_ALU64 | BPF_MOV | BPF_X:
|
||||
emit_mov_r(ctx, lo(dst), lo(src));
|
||||
emit_mov_r(ctx, hi(dst), hi(src));
|
||||
emit_mov_r64(ctx, dst, src, off);
|
||||
break;
|
||||
/* dst = -dst (64-bit) */
|
||||
case BPF_ALU64 | BPF_NEG:
|
||||
|
|
|
|||
|
|
@ -120,6 +120,58 @@ static void emit_zext_ver(struct jit_context *ctx, u8 dst)
|
|||
emit_zext(ctx, dst);
|
||||
}
|
||||
|
||||
/* Sign-extend an 8- or 16-bit field into a native register. */
|
||||
static void emit_movsx_r(struct jit_context *ctx, u8 dst, u8 src, s16 off)
|
||||
{
|
||||
/* seb/seh would need a sign-extended 32-bit source first. */
|
||||
int shift = 32 - off;
|
||||
|
||||
/* dsll32 and dsra32 add 32 to the shift argument. */
|
||||
emit(ctx, dsll32, dst, src, shift);
|
||||
emit(ctx, dsra32, dst, dst, shift);
|
||||
}
|
||||
|
||||
/* Register move operation (32-bit), optionally with sign extension */
|
||||
static void emit_mov_r32(struct jit_context *ctx, u8 dst, u8 src, s16 off)
|
||||
{
|
||||
switch (off) {
|
||||
case 8:
|
||||
case 16:
|
||||
emit_movsx_r(ctx, dst, src, off);
|
||||
break;
|
||||
default:
|
||||
/* off == 0 is MOV; the verifier rejects other offsets. */
|
||||
emit_mov_r(ctx, dst, src);
|
||||
break;
|
||||
}
|
||||
clobber_reg(ctx, dst);
|
||||
emit_zext_ver(ctx, dst);
|
||||
}
|
||||
|
||||
/* Register move operation (64-bit), optionally with sign extension */
|
||||
static void emit_mov_r64(struct jit_context *ctx, u8 dst, u8 src, s16 off)
|
||||
{
|
||||
switch (off) {
|
||||
case 8:
|
||||
case 16:
|
||||
emit_movsx_r(ctx, dst, src, off);
|
||||
break;
|
||||
case 32:
|
||||
emit_sext(ctx, dst, src);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* off == 0 is ordinary MOV. The verifier rejects other
|
||||
* offsets; defined exceptions require
|
||||
* bpf_jit_supports_percpu_insn() or bpf_jit_supports_arena(),
|
||||
* neither implemented by MIPS.
|
||||
*/
|
||||
emit_mov_r(ctx, dst, src);
|
||||
break;
|
||||
}
|
||||
clobber_reg(ctx, dst);
|
||||
}
|
||||
|
||||
/* dst = imm (64-bit) */
|
||||
static void emit_mov_i64(struct jit_context *ctx, u8 dst, u64 imm64)
|
||||
{
|
||||
|
|
@ -681,8 +733,7 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)
|
|||
/* Special mov32 for zext */
|
||||
emit_zext(ctx, dst);
|
||||
} else {
|
||||
emit_mov_r(ctx, dst, src);
|
||||
emit_zext_ver(ctx, dst);
|
||||
emit_mov_r32(ctx, dst, src, off);
|
||||
}
|
||||
break;
|
||||
/* dst = -dst */
|
||||
|
|
@ -767,7 +818,7 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)
|
|||
break;
|
||||
/* dst = src (64-bit) */
|
||||
case BPF_ALU64 | BPF_MOV | BPF_X:
|
||||
emit_mov_r(ctx, dst, src);
|
||||
emit_mov_r64(ctx, dst, src, off);
|
||||
break;
|
||||
/* dst = -dst (64-bit) */
|
||||
case BPF_ALU64 | BPF_NEG:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user