[PATCH v2] m68k: Add LTO support
Angelo Dureghello
angelo at kernel-space.org
Tue Mar 31 09:37:02 CEST 2026
Hi Daniel,
looks quite good to me, will re-test it asap, just have a questions:
On 3/31/26 00:01, Daniel Palmer wrote:
> Most m68k retro/homebrew machines will have limited flash/RAM
> so having LTO working would be nice.
>
> Not many changes are need really. Most of this is copy/paste
> from the ARM32 version.
>
> The major change is that the direct register usage of d7 for gd
> needs to be hidden so that when LTO passes over everything it
> doesn't see multiple instances of d7.
>
> Signed-off-by: Daniel Palmer <daniel at thingy.jp>
> ---
> arch/Kconfig | 1 +
> arch/m68k/config.mk | 8 ++++++--
> arch/m68k/cpu/m680x0/cpu.c | 2 +-
> arch/m68k/include/asm/global_data.h | 19 +++++++++++++++++++
> arch/m68k/lib/ashldi3.c | 6 ++++--
> arch/m68k/lib/lshrdi3.c | 6 ++++--
> arch/m68k/lib/muldi3.c | 4 +++-
> common/board_r.c | 4 ++--
> common/init/board_init.c | 4 ++--
> 9 files changed, 42 insertions(+), 12 deletions(-)
>
> diff --git a/arch/Kconfig b/arch/Kconfig
> index 4af0da2485fb..488de442f557 100644
> --- a/arch/Kconfig
> +++ b/arch/Kconfig
> @@ -112,6 +112,7 @@ config ARM
>
> config M68K
> bool "M68000 architecture"
> + select ARCH_SUPPORTS_LTO
> select HAVE_PRIVATE_LIBGCC
> select USE_PRIVATE_LIBGCC
> select SYS_BOOT_GET_CMDLINE
> diff --git a/arch/m68k/config.mk b/arch/m68k/config.mk
> index 458953f97122..4d8c83b51cdb 100644
> --- a/arch/m68k/config.mk
> +++ b/arch/m68k/config.mk
> @@ -8,9 +8,13 @@ ifneq ($(CONFIG_M680x0),y)
> PLATFORM_CPPFLAGS += -fPIC
> endif
> KBUILD_LDFLAGS += -n -pie
> -PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections
> PLATFORM_RELFLAGS += -ffixed-d7
> ifneq ($(CONFIG_M680x0),y)
> PLATFORM_RELFLAGS += -msep-data
> endif
> -LDFLAGS_FINAL += --gc-sections -pie
> +LDFLAGS_FINAL += -pie
> +
> +ifneq ($(LTO_ENABLE),y)
> +PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections
> +LDFLAGS_FINAL += --gc-sections
> +endif
> diff --git a/arch/m68k/cpu/m680x0/cpu.c b/arch/m68k/cpu/m680x0/cpu.c
> index f60b932c7dd4..3f87076b8c3d 100644
> --- a/arch/m68k/cpu/m680x0/cpu.c
> +++ b/arch/m68k/cpu/m680x0/cpu.c
> @@ -24,7 +24,7 @@ void m68k_virt_init_reserve(ulong base)
> for (i = 0; i < sizeof(*gd_ptr); i++)
> p[i] = 0;
>
> - gd = gd_ptr;
> + arch_setup_gd(gd);
>
> gd->malloc_base = base + sizeof(*gd_ptr);
> }
> diff --git a/arch/m68k/include/asm/global_data.h b/arch/m68k/include/asm/global_data.h
> index aea2ccabe083..9150ed4ab466 100644
> --- a/arch/m68k/include/asm/global_data.h
> +++ b/arch/m68k/include/asm/global_data.h
> @@ -32,6 +32,25 @@ struct arch_global_data {
>
> #include <asm-generic/global_data.h>
>
> +#if defined(LTO_ENABLE)
> +/* If LTO is enabled we have to hide d7 to avoid multiple symbol declarations */
> +#define DECLARE_GLOBAL_DATA_PTR
> +#define gd get_gd()
> +
> +static inline gd_t *get_gd(void)
> +{
> + gd_t *gd_ptr;
> +
> + __asm__ volatile("move.l %%d7, %0\n" : "=r" (gd_ptr));
> +
> + return gd_ptr;
> +}
> +#else
> #define DECLARE_GLOBAL_DATA_PTR register gd_t *gd asm ("d7")
> +#endif
> +static inline void arch_setup_gd(gd_t *new_gd)
> +{
> + __asm__ volatile("move.l %0, %%d7\n" : : "r" (new_gd));
> +}
>
> #endif /* __ASM_GBL_DATA_H */
> diff --git a/arch/m68k/lib/ashldi3.c b/arch/m68k/lib/ashldi3.c
> index 9a4bc676bf4c..9e84bd0d9a07 100644
> --- a/arch/m68k/lib/ashldi3.c
> +++ b/arch/m68k/lib/ashldi3.c
> @@ -6,6 +6,8 @@
> * Copyright (C) 1989-2015 Free Software Foundation, Inc.
> */
>
> +#include <linux/compiler_attributes.h>
> +
> #define BITS_PER_UNIT 8
>
> typedef int SItype __attribute__ ((mode (SI)));
> @@ -21,7 +23,7 @@ typedef union
> DItype ll;
> } DIunion;
>
> -DItype __ashldi3 (DItype u, word_type b)
> +__used DItype __ashldi3 (DItype u, word_type b)
Why the above __used is needed ? This impacts all the coldfire builds.
> {
> DIunion w;
> word_type bm;
> @@ -46,4 +48,4 @@ DItype __ashldi3 (DItype u, word_type b)
> }
>
> return w.ll;
> -}
> \ No newline at end of file
> +}
> diff --git a/arch/m68k/lib/lshrdi3.c b/arch/m68k/lib/lshrdi3.c
> index e639e676a269..53163bc5f83f 100644
> --- a/arch/m68k/lib/lshrdi3.c
> +++ b/arch/m68k/lib/lshrdi3.c
> @@ -6,6 +6,8 @@
> * Copyright (C) 1989-2015 Free Software Foundation, Inc.
> */
>
> +#include <linux/compiler_attributes.h>
> +
> #define BITS_PER_UNIT 8
>
> typedef int SItype __attribute__ ((mode (SI)));
> @@ -21,7 +23,7 @@ typedef union
> DItype ll;
> } DIunion;
>
> -DItype __lshrdi3 (DItype u, word_type b)
> +__used DItype __lshrdi3 (DItype u, word_type b)
> {
> DIunion w;
> word_type bm;
> @@ -46,4 +48,4 @@ DItype __lshrdi3 (DItype u, word_type b)
> }
>
> return w.ll;
> -}
> \ No newline at end of file
> +}
> diff --git a/arch/m68k/lib/muldi3.c b/arch/m68k/lib/muldi3.c
> index c42ca1d753e5..06af5533fde3 100644
> --- a/arch/m68k/lib/muldi3.c
> +++ b/arch/m68k/lib/muldi3.c
> @@ -6,6 +6,8 @@
> * Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
> */
>
> +#include <linux/compiler_attributes.h>
> +
> #define SI_TYPE_SIZE 32
> #define __BITS4 (SI_TYPE_SIZE / 4)
> #define __ll_B (1L << (SI_TYPE_SIZE / 2))
> @@ -54,7 +56,7 @@ typedef union
> DItype ll;
> } DIunion;
>
> -DItype __muldi3 (DItype u, DItype v)
> +__used DItype __muldi3 (DItype u, DItype v)
> {
> DIunion w;
> DIunion uu, vv;
> diff --git a/common/board_r.c b/common/board_r.c
> index 76f9fc090fbe..58eb69005468 100644
> --- a/common/board_r.c
> +++ b/common/board_r.c
> @@ -800,12 +800,12 @@ void board_init_r(gd_t *new_gd, ulong dest_addr)
> * TODO(sjg at chromium.org): Consider doing this for all archs, or
> * dropping the new_gd parameter.
> */
> - if (CONFIG_IS_ENABLED(X86_64) && !IS_ENABLED(CONFIG_EFI_APP))
> + if ((CONFIG_IS_ENABLED(X86_64) && !IS_ENABLED(CONFIG_EFI_APP)) || CONFIG_IS_ENABLED(M68K))
> arch_setup_gd(new_gd);
>
> #if defined(CONFIG_RISCV)
> set_gd(new_gd);
> -#elif !defined(CONFIG_X86) && !defined(CONFIG_ARM) && !defined(CONFIG_ARM64)
> +#elif !defined(CONFIG_X86) && !defined(CONFIG_ARM) && !defined(CONFIG_ARM64) && !defined(CONFIG_M68K)
> gd = new_gd;
> #endif
> gd->flags &= ~GD_FLG_LOG_READY;
> diff --git a/common/init/board_init.c b/common/init/board_init.c
> index 2a6f39f51adb..31b499ebad9c 100644
> --- a/common/init/board_init.c
> +++ b/common/init/board_init.c
> @@ -14,10 +14,10 @@
> DECLARE_GLOBAL_DATA_PTR;
>
> /*
> - * Unfortunately x86, ARM and RISC-V can't compile this code as gd is defined
> + * Unfortunately x86, ARM, RISC-V, M68K can't compile this code as gd is defined
> * as macro and cannot be assigned.
> */
> -#if !defined(CONFIG_X86) && !defined(CONFIG_ARM) && !defined(CONFIG_RISCV)
> +#if !defined(CONFIG_X86) && !defined(CONFIG_ARM) && !defined(CONFIG_RISCV) && !defined(CONFIG_M68K)
> __weak void arch_setup_gd(struct global_data *gd_ptr)
> {
> gd = gd_ptr;
Regards,
-- Angelo
More information about the U-Boot
mailing list