diff --git a/Makefile b/Makefile index 88b5b7d99c..497ab89622 100644 --- a/Makefile +++ b/Makefile @@ -108,11 +108,16 @@ ELF2ROM := tools/elf2rom ZAPD := tools/ZAPD/ZAPD.out FADO := tools/fado/fado.elf -OPTFLAGS := -O2 +ifeq ($(COMPILER),gcc) + OPTFLAGS := -Os -ffast-math -fno-unsafe-math-optimizations +else + OPTFLAGS := -O2 +endif + ASFLAGS := -march=vr4300 -32 -Iinclude ifeq ($(COMPILER),gcc) - CFLAGS += -G 0 -nostdinc $(INC) -DNON_MATCHING=1 -DAVOID_UB=1 -march=vr4300 -mfix4300 -mabi=32 -mdivide-breaks -fno-common -fno-zero-initialized-in-bss -mno-abicalls -fno-toplevel-reorder -ffreestanding $(CHECK_WARNINGS) -g -mno-explicit-relocs -mno-split-addresses -funsigned-char + CFLAGS += -G 0 -nostdinc $(INC) -D AVOID_UB -march=vr4300 -mfix4300 -mabi=32 -mno-abicalls -mdivide-breaks -fno-zero-initialized-in-bss -fno-toplevel-reorder -ffreestanding -fno-common -fno-merge-constants -mno-explicit-relocs -mno-split-addresses $(CHECK_WARNINGS) -funsigned-char MIPS_VERSION := -mips3 else # we support Microsoft extensions such as anonymous structs, which the compiler does support but warns for their usage. Surpress the warnings with -woff. @@ -207,6 +212,7 @@ build/src/overlays/%.o: CC := python3 tools/asm_processor/build.py $(CC) -- $(AS build/assets/%.o: CC := python3 tools/asm_processor/build.py $(CC) -- $(AS) $(ASFLAGS) -- else +build/src/libultra/libc/ll.o: OPTFLAGS := -Ofast build/src/%.o: CC := $(CC) -fexec-charset=euc-jp endif diff --git a/src/boot/missing_gcc_functions.c b/src/boot/missing_gcc_functions.c index 628b59e685..441a1b8aea 100644 --- a/src/boot/missing_gcc_functions.c +++ b/src/boot/missing_gcc_functions.c @@ -66,3 +66,23 @@ f32 __floatundisf(u32 c) { f64 __floatundidf(u32 c) { return (f64)c; } + +f32 __powisf2(f32 a, s32 b) { + const s32 recip = b < 0; + f32 r = 1; + + while (1) { + if (b & 1) { + r *= a; + } + + b /= 2; + + if (b == 0) { + break; + } + + a *= a; + } + return recip ? 1/r : r; +} \ No newline at end of file diff --git a/src/overlays/actors/ovl_En_Zf/z_en_zf.c b/src/overlays/actors/ovl_En_Zf/z_en_zf.c index a8d90a4a80..38f3034cb0 100644 --- a/src/overlays/actors/ovl_En_Zf/z_en_zf.c +++ b/src/overlays/actors/ovl_En_Zf/z_en_zf.c @@ -452,9 +452,15 @@ s16 EnZf_FindNextPlatformAwayFromPlayer(Vec3f* pos, s16 curPlatform, s16 arg2, G } } - // These functions have no side effects, so these two calls do nothing + //! @bug `altNextPlatform` can be -1 in certain conditions and cause an out of bounds access. + //! Under normal conditions, this doesn't cause problems because the data before `sPlatformPositions` + //! is section padding between .text and .data, so 0 gets read as a float. + //! Other compilers can shift things and result in a crash. Defining `AVOID_UB` will remove these function calls + //! entirely as they are dead code and do not have any effect. + #ifndef AVOID_UB Math_Vec3f_DistXYZ(&player->actor.world.pos, &sPlatformPositions[nextPlatform]); Math_Vec3f_DistXYZ(&player->actor.world.pos, &sPlatformPositions[altNextPlatform]); + #endif if (altNextPlatform > 0) { s16 nextPlatformToPlayerYaw = diff --git a/tools/mkldscript.c b/tools/mkldscript.c index 2239e864e2..b145f54adc 100644 --- a/tools/mkldscript.c +++ b/tools/mkldscript.c @@ -60,6 +60,7 @@ static void write_ld_script(FILE *fout) for (j = 0; j < seg->includesCount; j++) { fprintf(fout, " %s (.text)\n", seg->includes[j].fpath); + fprintf(fout, " . = ALIGN(0x10);\n"); if (seg->includes[j].linkerPadding != 0) fprintf(fout, " . += 0x%X;\n", seg->includes[j].linkerPadding); } @@ -72,8 +73,10 @@ static void write_ld_script(FILE *fout) for (j = 0; j < seg->includesCount; j++) { - if (!seg->includes[j].dataWithRodata) + if (!seg->includes[j].dataWithRodata) { fprintf(fout, " %s (.data)\n", seg->includes[j].fpath); + fprintf(fout, " . = ALIGN(0x10);\n"); + } } /* @@ -93,9 +96,12 @@ static void write_ld_script(FILE *fout) for (j = 0; j < seg->includesCount; j++) { - if (seg->includes[j].dataWithRodata) + if (seg->includes[j].dataWithRodata) { fprintf(fout, " %s (.data)\n", seg->includes[j].fpath); + fprintf(fout, " . = ALIGN(0x10);\n"); + } fprintf(fout, " %s (.rodata)\n", seg->includes[j].fpath); + fprintf(fout, " . = ALIGN(0x10);\n"); // Compilers other than IDO, such as GCC, produce different sections such as // the ones named directly below. These sections do not contain values that // need relocating, but we need to ensure that the base .rodata section @@ -105,8 +111,11 @@ static void write_ld_script(FILE *fout) // Inconsistencies will lead to various .rodata reloc crashes as a result of // either missing relocs or wrong relocs. fprintf(fout, " %s (.rodata.str1.4)\n", seg->includes[j].fpath); + fprintf(fout, " . = ALIGN(0x10);\n"); fprintf(fout, " %s (.rodata.cst4)\n", seg->includes[j].fpath); + fprintf(fout, " . = ALIGN(0x10);\n"); fprintf(fout, " %s (.rodata.cst8)\n", seg->includes[j].fpath); + fprintf(fout, " . = ALIGN(0x10);\n"); } //fprintf(fout, " . = ALIGN(0x10);\n"); @@ -162,8 +171,10 @@ static void write_ld_script(FILE *fout) fprintf(fout, " %s (.sbss)\n", seg->includes[j].fpath); for (j = 0; j < seg->includesCount; j++) fprintf(fout, " %s (.scommon)\n", seg->includes[j].fpath); - for (j = 0; j < seg->includesCount; j++) + for (j = 0; j < seg->includesCount; j++) { + fprintf(fout, " . = ALIGN(0x10);\n"); fprintf(fout, " %s (.bss)\n", seg->includes[j].fpath); + } for (j = 0; j < seg->includesCount; j++) fprintf(fout, " %s (COMMON)\n", seg->includes[j].fpath); fprintf(fout, " . = ALIGN(0x10);\n"