Messages in this thread Patch in this message |  | | From | Daniel Palmer <> | | Subject | [PATCH] m68k: implement runtime consts | | Date | Thu, 27 Nov 2025 09:05:04 +0900 |
| |
This implements runtime consts for m68k which hopefully improves performance a tiny bit, maybe, hopefully... going downhill with the wind behind us.
Constant pointers are just a register load with an immediate that is fixed up.
Constant shifts are a very small register load with an immediate that is fixed up and then the val is shifted by the register. Putting the shift amount in a register is needed as the shift instruction can only encode a maximum of shift by 8 with an immediate.
Before:
0013c6ea <__d_lookup_rcu_op_compare>: ... 13c6fc: 2003 movel %d3,%d0 13c6fe: 2239 0069 a980 movel 69a980 <d_hash_shift>,%d1 13c704: e2a8 lsrl %d1,%d0 13c706: e588 lsll #2,%d0 13c708: d0b9 0069 a97c addl 69a97c <dentry_hashtable>,%d0 ...
After:
0013c6c0 <__d_lookup_rcu_op_compare>: ... 13c6d2: 207c cafe f00d moveal #-889262067,%a0 13c6d8: 2003 movel %d3,%d0 13c6da: 720c moveq #12,%d1 13c6dc: e2a8 lsrl %d1,%d0 13c6de: e588 lsll #2,%d0 13c6e0: d1c0 addal %d0,%a0 ...
Signed-off-by: Daniel Palmer <daniel@thingy.jp> --- arch/m68k/include/asm/runtime-const.h | 76 +++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 arch/m68k/include/asm/runtime-const.h
diff --git a/arch/m68k/include/asm/runtime-const.h b/arch/m68k/include/asm/runtime-const.h new file mode 100644 index 000000000000..576031c5b808 --- /dev/null +++ b/arch/m68k/include/asm/runtime-const.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * runtime const implementation for m68k + * Copyright (C) 2025 Daniel Palmer<daniel@thingy.jp> + * + * Based on arm64 version. + */ +#ifndef _ASM_RUNTIME_CONST_H +#define _ASM_RUNTIME_CONST_H + +#include <asm/cacheflush.h> +#include <linux/bitfield.h> + +#define runtime_const_ptr(sym) ({ \ + typeof(sym) __ret; \ + asm_inline("1:\t" \ + "mov.l #0xcafef00d,%0\n\t" \ + ".pushsection runtime_ptr_" #sym ",\"a\"\n\t" \ + ".long 1b - .\n\t" \ + ".popsection" \ + : "=a" (__ret)); \ + __ret; }) + +static inline void __runtime_fixup_ptr(void *where, unsigned long val) +{ + u32 *value = where + 2; + const unsigned long start = ((unsigned long) where) + 2; + const unsigned long end = start + sizeof(*value); + + *value = val; + + flush_icache_range(start, end); +} + +#define runtime_const_shift_right_32(val, sym) ({ \ + u32 __tmp; \ + asm_inline("1:\t" \ + "moveq #12, %0\n\t" \ + "lsr.l %0, %1\n\t" \ + ".pushsection runtime_shift_" #sym ",\"a\"\n\t" \ + ".long 1b - .\n\t" \ + ".popsection" \ + : "=&d" (__tmp), "+d" (val)); \ + val; }) + +#define MOVEQ_DATA GENMASK(7, 0) +static inline void __runtime_fixup_shift(void *where, unsigned long val) +{ + u16 *insn = where; + const unsigned long start = (unsigned long) where; + const unsigned long end = start + sizeof(*insn); + + FIELD_MODIFY(MOVEQ_DATA, insn, val); + + flush_icache_range(start, end); +} + +#define runtime_const_init(type, sym) do { \ + extern s32 __start_runtime_##type##_##sym[]; \ + extern s32 __stop_runtime_##type##_##sym[]; \ + runtime_const_fixup(__runtime_fixup_##type, \ + (unsigned long)(sym), \ + __start_runtime_##type##_##sym, \ + __stop_runtime_##type##_##sym); \ +} while (0) + +static inline void runtime_const_fixup(void (*fn)(void *, unsigned long), + unsigned long val, s32 *start, s32 *end) +{ + while (start < end) { + fn(*start + (void *)start, val); + start++; + } +} + +#endif -- 2.51.0
|  |