diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 30231dbd0f..8620999045 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,6 +31,12 @@ jobs: env: COMPARE: 0 run: make -j${nproc} -O all + + - name: LTO + run: | + make tidy + make -j${nproc} LTO=1 + # make tidy to purge previous build - name: Test env: diff --git a/Makefile b/Makefile index 735bd25454..ebf7679af3 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,8 @@ ANALYZE ?= 0 UNUSED_ERROR ?= 0 # Adds -Og and -g flags, which optimize the build for debugging and include debug info respectively DEBUG ?= 0 +# Adds -flto flag, which increases link time but results in a more efficient binary (especially in audio processing) +LTO ?= 0 ifeq (compare,$(MAKECMDGOALS)) COMPARE := 1 @@ -106,7 +108,7 @@ TEST_BUILDDIR = $(OBJ_DIR)/$(TEST_SUBDIR) SHELL := bash -o pipefail # Set flags for tools -ASFLAGS := -mcpu=arm7tdmi --defsym MODERN=1 +ASFLAGS := -mcpu=arm7tdmi -march=armv4t -meabi=5 --defsym MODERN=1 INCLUDE_DIRS := include INCLUDE_CPP_ARGS := $(INCLUDE_DIRS:%=-iquote %) @@ -121,7 +123,15 @@ CPPFLAGS := $(INCLUDE_CPP_ARGS) -Wno-trigraphs -DMODERN=1 -DTESTING=$(TEST) -std ARMCC := $(PREFIX)gcc PATH_ARMCC := PATH="$(PATH)" $(ARMCC) CC1 := $(shell $(PATH_ARMCC) --print-prog-name=cc1) -quiet + override CFLAGS += -mthumb -mthumb-interwork -O$(O_LEVEL) -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -Wno-pointer-to-int-cast -std=gnu17 -Werror -Wall -Wno-strict-aliasing -Wno-attribute-alias -Woverride-init + +ifneq ($(LTO),0) + ifneq ($(TEST),1) + override CFLAGS += -flto=auto -fno-fat-lto-objects -fno-asynchronous-unwind-tables -ffunction-sections -fdata-sections + endif +endif + ifeq ($(ANALYZE),1) override CFLAGS += -fanalyzer endif @@ -283,7 +293,7 @@ agbcc: LD_SCRIPT_TEST := ld_script_test.ld -$(OBJ_DIR)/ld_script_test.ld: $(LD_SCRIPT_TEST) $(LD_SCRIPT_DEPS) +$(OBJ_DIR)/ld_script_test.ld: $(LD_SCRIPT_TEST) cd $(OBJ_DIR) && sed "s#tools/#../../tools/#g" ../../$(LD_SCRIPT_TEST) > ld_script_test.ld $(TESTELF): $(OBJ_DIR)/ld_script_test.ld $(OBJS) $(TEST_OBJS) libagbsyscall tools check-tools @@ -476,19 +486,28 @@ $(DATA_SRC_SUBDIR)/pokemon/teachable_learnsets.h: $(TEACHABLE_DEPS) # Linker script LD_SCRIPT := ld_script_modern.ld -LD_SCRIPT_DEPS := # Final rules libagbsyscall: @$(MAKE) -C libagbsyscall TOOLCHAIN=$(TOOLCHAIN) MODERN=1 -# Elf from object files -LDFLAGS = -Map ../../$(MAP) -$(ELF): $(LD_SCRIPT) $(LD_SCRIPT_DEPS) $(OBJS) libagbsyscall - @cd $(OBJ_DIR) && $(LD) $(LDFLAGS) -T ../../$< --print-memory-usage -o ../../$@ $(OBJS_REL) $(LIB) | cat - @echo "cd $(OBJ_DIR) && $(LD) $(LDFLAGS) -T ../../$< --print-memory-usage -o ../../$@ | cat" +# Enable LTO LDFLAGS if set +ifneq ($(LTO),0) +LDFLAGS := -march=armv4t -mabi=apcs-gnu -mcpu=arm7tdmi -Xlinker -Map=../../$(MAP) -Xlinker --print-memory-usage -Xassembler -meabi=5 -Xassembler -march=armv4t -Xassembler -mcpu=arm7tdmi -Xlinker --gc-sections +LDFLAGS += -Xlinker -flto=auto +$(ELF): $(LD_SCRIPT) $(OBJS) libagbsyscall + @echo "cd $(OBJ_DIR) && $(ARMCC) $(LDFLAGS) -T ../../$< -o ../../$@ " + +@cd $(OBJ_DIR) && $(ARMCC) $(LDFLAGS) -T ../../$< -o ../../$@ $(OBJS_REL) $(LIB) $(FIX) $@ -t"$(TITLE)" -c$(GAME_CODE) -m$(MAKER_CODE) -r$(REVISION) --silent +else +# Output .map file, memory usage readout and gc sections to clean-up unused data +LDFLAGS = -Map ../../$(MAP) --print-memory-usage --gc-sections +$(ELF): $(LD_SCRIPT) $(OBJS) libagbsyscall + @cd $(OBJ_DIR) && $(LD) $(LDFLAGS) -T ../../$< -o ../../$@ $(OBJS_REL) $(LIB) | cat + @echo "cd $(OBJ_DIR) && $(LD) $(LDFLAGS) -T ../../$< -o ../../$@ | cat" + $(FIX) $@ -t"$(TITLE)" -c$(GAME_CODE) -m$(MAKER_CODE) -r$(REVISION) --silent +endif # Builds the rom from the elf file $(ROM): $(ELF) diff --git a/ld_script_modern.ld b/ld_script_modern.ld index ee4713ab17..f021ac2916 100644 --- a/ld_script_modern.ld +++ b/ld_script_modern.ld @@ -26,7 +26,7 @@ SECTIONS { .ewram.sbss (NOLOAD) : ALIGN(4) { - src/*.o(.sbss); + *.o(.sbss); } > EWRAM .iwram ORIGIN(IWRAM) : AT (__iwram_lma) @@ -41,14 +41,8 @@ SECTIONS { .iwram.bss (NOLOAD) : ALIGN(4) { - src/*.o(.bss); - data/*.o(.bss); - *libc.a:*.o(.bss*); - *libnosys.a:*.o(.bss*); - - src/m4a.o(.bss.code); - - src/*.o(common_data); + *.o(.bss*); + *.o(common_data); src/*.o(COMMON); *libc.a:*.o(COMMON); *libnosys.a:*.o(COMMON); @@ -63,9 +57,13 @@ SECTIONS { src/rom_header_gf.o(.text.*); src/rom_header_rhh.o(.text.*); src/crt0.o(.text); - src/main.o(.text); - src/*.o(.text*); + *libagbsyscall.a:*.o(.text*); + *libgcc.a:*.o(.text*); + *libc.a:*.o(.text*); + *libnosys.a:*.o(.text*); asm/*.o(.text*); + *.o(.text*); + *.o(.eh_frame); } > ROM =0 script_data : @@ -74,69 +72,14 @@ SECTIONS { data/*.o(script_data); } > ROM =0 - lib_text : - ALIGN(4) - { - src/libgcnmultiboot.o(.text); - src/m4a_1.o(.text); - src/m4a.o(.text); - src/agb_flash.o(.text); - src/agb_flash_1m.o(.text); - src/agb_flash_mx.o(.text); - src/siirtc.o(.text); - src/librfu_stwi.o(.text); - src/librfu_intr.o(.text); - src/librfu_rfu.o(.text); - src/librfu_sio32id.o(.text); - *libagbsyscall.a:*.o(.text*); - *libgcc.a:*.o(.text*); - *libc.a:*.o(.text*); - *libnosys.a:*.o(.text*); - src/libisagbprn.o(.text); - } > ROM =0 - .rodata : ALIGN(4) { - src/*.o(.rodata*); - data/*.o(.rodata*); - } > ROM =0 - - song_data : - ALIGN(4) - { - sound/songs/*.o(.rodata); - } > ROM =0 - - lib_rodata : - SUBALIGN(4) - { - src/m4a.o(.rodata); - src/agb_flash.o(.rodata); - src/agb_flash_1m.o(.rodata); - src/agb_flash_mx.o(.rodata); - src/agb_flash_le.o(.rodata); - src/siirtc.o(.rodata); - src/librfu_rfu.o(.rodata); - src/librfu_sio32id.o(.rodata); + *.o(.rodata*); *libgcc.a:*.o(.rodata*); *libc.a:*.o(.rodata*); *libc.a:*.o(.data*); - src/libisagbprn.o(.rodata); - } > ROM =0 - - multiboot_data : - ALIGN(4) - { - data/multiboot_ereader.o(.rodata); - data/multiboot_berry_glitch_fix.o(.rodata); - data/multiboot_pokemon_colosseum.o(.rodata); - } > ROM =0 - - gfx_data : - ALIGN(4) - { - src/graphics.o(.rodata); + sound/songs/*.o(.rodata); } > ROM =0 .data.iwram : diff --git a/src/dodrio_berry_picking.c b/src/dodrio_berry_picking.c index 8f29f498f0..2593719022 100644 --- a/src/dodrio_berry_picking.c +++ b/src/dodrio_berry_picking.c @@ -3099,6 +3099,7 @@ struct ReadyToStartPacket { u8 id; bool8 ALIGNED(4) ready; + u32 unused; // Put here, so that packet has the same size as gRfu.packet(12 bytes). }; static void SendPacket_ReadyToStart(bool32 ready) @@ -3303,6 +3304,7 @@ struct PickStatePacket { u8 id; u8 ALIGNED(4) pickState; + u32 unused; // Put here, so that packet has the same size as gRfu.packet(12 bytes). }; static void SendPacket_PickState(u8 pickState) @@ -3334,6 +3336,7 @@ struct ReadyToEndPacket { u8 id; bool32 ready; + u32 unused; // Put here, so that packet has the same size as gRfu.packet(12 bytes). }; static void SendPacket_ReadyToEnd(bool32 ready) diff --git a/src/strings.c b/src/strings.c index 314d7536dc..4846bea8ed 100644 --- a/src/strings.c +++ b/src/strings.c @@ -18,8 +18,8 @@ const u8 gText_ExpandedPlaceholder_Kyogre[] = _("KYOGRE"); const u8 gText_ExpandedPlaceholder_Groudon[] = _("GROUDON"); const u8 gText_ExpandedPlaceholder_Brendan[] = _("BRENDAN"); const u8 gText_ExpandedPlaceholder_May[] = _("MAY"); -const u8 gText_EggNickname[] = _("EGG"); -const u8 gText_Pokemon[] = _("POKéMON"); +const u8 gText_EggNickname[POKEMON_NAME_LENGTH + 1] = _("EGG"); +const u8 gText_Pokemon[POKEMON_NAME_LENGTH + 1] = _("POKéMON"); const u8 gText_Player[] = _("PLAYER"); // Unused const u8 gText_Pokedex[] = _("POKéDEX"); // Unused const u8 gText_Time[] = _("TIME");