Initial GCC Support (#212)

* first try

* progress

* progress

* gcc compiling, rom not booting yet

* format

* restore word compiler

* comment

* fix

* fix

* fix addresses for new splat

* progress

* splat

* we don't need these anymore

* gcc build seems stable now
This commit is contained in:
Alejandro Asenjo Nitti
2024-04-15 20:15:45 -03:00
committed by GitHub
parent 3efafe60e3
commit 1ee6762797
9 changed files with 252 additions and 16 deletions
+91 -8
View File
@@ -25,6 +25,8 @@ CC_CHECK_COMP ?= gcc
OBJDUMP_BUILD ?= 0
# Number of threads to compress with
N_THREADS ?= $(shell nproc)
# If COMPILER is GCC, compile with GCC instead of IDO.
COMPILER ?= ido
# Whether to colorize build messages
COLOR ?= 1
# Whether to hide commands or not
@@ -63,6 +65,57 @@ LD_SCRIPT := linker_scripts/$(VERSION)/$(TARGET).ld
#### Setup ####
# If gcc is used, define the NON_MATCHING flag respectively so the files that
# are safe to be used can avoid using GLOBAL_ASM which doesn't work with gcc.
ifeq ($(COMPILER),gcc)
$(warning WARNING: GCC support is experimental. Use at your own risk.)
CFLAGS += -DCOMPILER_GCC
NON_MATCHING := 1
endif
# Detect compiler and set variables appropriately.
ifeq ($(COMPILER),gcc)
CC := $(MIPS_BINUTILS_PREFIX)gcc
else
ifeq ($(COMPILER),ido)
CC := tools/ido_recomp/$(DETECTED_OS)/7.1/cc
CC_OLD := tools/ido_recomp/$(DETECTED_OS)/5.3/cc
else
$(error Unsupported compiler. Please use either ido or gcc as the COMPILER variable.)
endif
endif
# ditch g3, we aren't using that in GCC
ifeq ($(COMPILER),gcc)
OPTFLAGS := -Os
else
OPTFLAGS := -O2 -g3
endif
ifeq ($(COMPILER),gcc)
CFLAGS += -G 0 -ffast-math -fno-unsafe-math-optimizations -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.
CFLAGS += -G 0 -non_shared -fullwarn -verbose -Xcpluscomm $(IINC) -nostdinc -Wab,-r4300_mul -woff 649,838,712,516
MIPS_VERSION := -mips2
endif
ifeq ($(COMPILER),ido)
# Have CC_CHECK pretend to be a MIPS compiler
MIPS_BUILTIN_DEFS := -D_MIPS_ISA_MIPS2=2 -D_MIPS_ISA=_MIPS_ISA_MIPS2 -D_ABIO32=1 -D_MIPS_SIM=_ABIO32 -D_MIPS_SZINT=32 -D_MIPS_SZLONG=32 -D_MIPS_SZPTR=32
CC_CHECK = gcc -fno-builtin -fsyntax-only -funsigned-char -std=gnu90 -D_LANGUAGE_C -DNON_MATCHING $(MIPS_BUILTIN_DEFS) $(IINC) $(CHECK_WARNINGS)
ifeq ($(shell getconf LONG_BIT), 32)
# Work around memory allocation bug in QEMU
export QEMU_GUEST_BASE := 1
else
# Ensure that gcc (warning check) treats the code as 32-bit
CC_CHECK += -m32
endif
else
CC_CHECK = @:
endif
BUILD_DEFINES ?=
ifeq ($(VERSION),us)
@@ -73,7 +126,7 @@ endif
ifeq ($(NON_MATCHING),1)
BUILD_DEFINES += -DNON_MATCHING -DAVOID_UB
COMPARE := 0
CPPFLAGS += -DNON_MATCHING -DAVOID_UB
endif
MAKE = make
@@ -190,10 +243,6 @@ else
CC_CHECK := @:
endif
CFLAGS += -G 0 -non_shared -Xcpluscomm -nostdinc -Wab,-r4300_mul
WARNINGS := -fullwarn -verbose -woff 624,649,838,712,516,513,596,564,594,709
ASFLAGS := -march=vr4300 -32 -G0
COMMON_DEFINES := -D_MIPS_SZLONG=32
GBI_DEFINES := -DF3DEX_GBI
@@ -202,8 +251,6 @@ AS_DEFINES := -DMIPSEB -D_LANGUAGE_ASSEMBLY -D_ULTRA64
C_DEFINES := -DLANGUAGE_C -D_LANGUAGE_C -DBUILD_VERSION=VERSION_H ${RELEASE_DEFINES}
ENDIAN := -EB
OPTFLAGS := -O2 -g3
MIPS_VERSION := -mips2
ICONV_FLAGS := --from-code=UTF-8 --to-code=EUC-JP
# Use relocations and abi fpr names in the dump
@@ -247,6 +294,9 @@ DEP_FILES := $(O_FILES:.o=.d) \
# create build directories
$(shell mkdir -p $(BUILD_DIR)/linker_scripts/$(VERSION) $(BUILD_DIR)/linker_scripts/$(VERSION)/auto $(foreach dir,$(SRC_DIRS) $(ASM_DIRS) $(BIN_DIRS),$(BUILD_DIR)/$(dir)))
ifeq ($(COMPILER),ido)
CFLAGS += -G 0 -non_shared -Xcpluscomm -nostdinc -Wab,-r4300_mul
WARNINGS := -fullwarn -verbose -woff 624,649,838,712,516,513,596,564,594,709
# directory flags
build/src/libultra/gu/%.o: OPTFLAGS := -O3 -g0
@@ -281,8 +331,41 @@ build/src/libultra/gu/mtxutil.o: CC := $(IDO)
build/src/libultra/gu/cosf.o: CC := $(IDO)
build/src/libultra/libc/xprintf.o: CC := $(IDO)
build/src/libultra/libc/xldtob.o: CC := $(IDO)
else
# directory flags
build/src/libultra/gu/%.o: OPTFLAGS := -Os
build/src/libultra/io/%.o: OPTFLAGS := -Os
build/src/libultra/os/%.o: OPTFLAGS := -Os
build/src/libultra/rmon/%.o: OPTFLAGS := -Os
build/src/libultra/debug/%.o: OPTFLAGS := -Os
build/src/libultra/host/%.o: OPTFLAGS := -Os
build/src/audio/audio_load.o: OPTFLAGS := -Os # Crashes with -O2 and -O3
build/src/audio/%.o: OPTFLAGS := -O2 -g
#build/src/%.o: CC := $(ASM_PROC) $(ASM_PROC_FLAGS) $(IDO) -- $(AS) $(ASFLAGS) --
# per-file flags
build/src/libc_sprintf.o: OPTFLAGS := -Os
build/src/libc_math64.o: OPTFLAGS := -Os
build/src/libultra/libc/ldiv.o: OPTFLAGS := -Os
build/src/libultra/libc/string.o: OPTFLAGS := -Os
build/src/libultra/libc/xlitob.o: OPTFLAGS := -Os
build/src/libultra/libc/xldtob.o: OPTFLAGS := -Os
build/src/libultra/libc/xprintf.o: OPTFLAGS := -Os
build/src/libultra/libc/ll.o: OPTFLAGS := -Os
build/src/libultra/libc/ll.o: MIPS_VERSION := -mips3
# cc & asm-processor
build/src/libultra/gu/sqrtf.o: OPTFLAGS := -Os
build/src/libultra/gu/sinf.o: OPTFLAGS := -Os
build/src/libultra/gu/lookat.o: OPTFLAGS := -Os
build/src/libultra/gu/ortho.o: OPTFLAGS := -Os
build/src/libultra/libc/ll.o: OPTFLAGS := -Os
build/src/libultra/gu/perspective.o: OPTFLAGS := -Os
build/src/libultra/gu/mtxutil.o: OPTFLAGS := -Os
build/src/libultra/gu/cosf.o: OPTFLAGS := -Os
build/src/libultra/libc/xprintf.o: OPTFLAGS := -Os
build/src/libultra/libc/xldtob.o: OPTFLAGS := -Os
endif
all: uncompressed
+2
View File
@@ -41,7 +41,9 @@ double fabs(double f);
#endif
float sqrtf(float f);
#if defined(__sgi)
#pragma intrinsic(sqrtf)
#endif
double sqrt(double d);
#pragma intrinsic(sqrt)
+5 -1
View File
@@ -765,6 +765,7 @@ u8* AudioHeap_AllocPermanent(s32 tableType, s32 id, u32 size) {
ramAddr = AudioHeap_Alloc(&gPermanentPool.pool, size);
gPermanentPool.entry[index].ramAddr = ramAddr;
if (ramAddr == NULL) {
return NULL;
}
@@ -772,7 +773,10 @@ u8* AudioHeap_AllocPermanent(s32 tableType, s32 id, u32 size) {
gPermanentPool.entry[index].tableType = tableType;
gPermanentPool.entry[index].id = id;
gPermanentPool.entry[index].size = size;
// return temp;
#ifdef AVOID_UB
return ramAddr;
#endif
}
void* AudioHeap_AllocTemporarySampleCache(s32 size, s32 fontId, s32 sampleAddr, s8 medium) {
+1 -1
View File
@@ -280,7 +280,7 @@ u16 gHaasEffectDelaySizes[64] = {
};
// clang-format off
s16 D_800DD200[] = {
ALIGNED(16) s16 D_800DD200[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
+7 -6
View File
@@ -1,7 +1,7 @@
#include "sys.h"
// clang-format off
s16 gSawtoothWaveSample[] = {
ALIGNED(16) s16 gSawtoothWaveSample[] = {
// Frequency of 1
0, 1023, 2047, 3071, 4095, 5119, 6143, 7167,
8191, 9215, 10239, 11263, 12287, 13311, 14335, 15359,
@@ -43,7 +43,7 @@ s16 gSawtoothWaveSample[] = {
0, 8191, 16383, 24575, -32767, -24575, -16383, -8191,
};
s16 gTriangleWaveSample[] = {
ALIGNED(16) s16 gTriangleWaveSample[] = {
// Frequency of 1
0, 2047, 4095, 6143, 8191, 10239, 12287, 14335,
16383, 18431, 20479, 22527, 24575, 26623, 28671, 30719,
@@ -85,7 +85,7 @@ s16 gTriangleWaveSample[] = {
0, 16383, 32767, 16383, 0, -16383, -32767, -16383,
};
s16 gSineWaveSample[] = {
ALIGNED(16) s16 gSineWaveSample[] = {
// Frequency of 1
0, 3211, 6392, 9511, 12539, 15446, 18204, 20787,
23169, 25329, 27244, 28897, 30272, 31356, 32137, 32609,
@@ -127,7 +127,7 @@ s16 gSineWaveSample[] = {
0, 23169, 32767, 23169, 0, -23169, -32767, -23169,
};
s16 gSquareWaveSample[] = {
ALIGNED(16) s16 gSquareWaveSample[] = {
// Frequency of 1
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
@@ -169,7 +169,7 @@ s16 gSquareWaveSample[] = {
0, 0, 32767, 32767, 0, 0, -32767, -32767,
};
s16 gWhiteNoiseSample[] = {
ALIGNED(16) s16 gWhiteNoiseSample[] = {
// Frequency of 1
0, -25689, -25791, 27803, -27568, -21030, 22174, 6298,
27071, -18531, 28649, 2284, 3380, 6890, -12682, -21114,
@@ -212,7 +212,7 @@ s16 gWhiteNoiseSample[] = {
};
// Sine White Noise?
s16 gUnkSample[] = {
ALIGNED(16) s16 gUnkSample[] = {
// Frequency of 1
0, 16316, 20148, 20257, 27209, -32657, 29264, 27259,
-29394, -21494, -26410, 30770, 30033, 29130, 20206, 14129,
@@ -255,6 +255,7 @@ s16 gUnkSample[] = {
};
// clang-format on
ALIGNED(16)
s16* gWaveSamples[] = {
gSawtoothWaveSample, gTriangleWaveSample, gSineWaveSample, gSquareWaveSample, gWhiteNoiseSample, gUnkSample,
};
+130
View File
@@ -0,0 +1,130 @@
/* --------------------------------------------------------------------------------*/
/* Depending on the toolchain used, an appropriate precompiled libgcc library */
/* may not exist and cannot be linked against. Until we have a better work around, */
/* necessary gcc functions are hosted here in order to properly compile. */
/* This file is NOT a part of the original game and only exists to help gcc work. */
/* --------------------------------------------------------------------------------*/
asm(" \n\
.set push \n\
.set noat \n\
.set noreorder \n\
.set gp=64 \n\
\n\
.global sqrtf \n\
sqrtf: \n\
jr $ra \n\
sqrt.s $f0, $f12 \n\
nop \n\
nop \n\
\n");
asm(" \n\
.set push \n\
.set noat \n\
.set noreorder \n\
.set gp=64 \n\
\n\
.global __umoddi3 \n\
__umoddi3: \n\
.type __umoddi3, @function \n\
.ent __umoddi3 \n\
sw $a0, ($sp) \n\
sw $a1, 4($sp) \n\
sw $a2, 8($sp) \n\
sw $a3, 0xc($sp) \n\
ld $t7, 8($sp) \n\
ld $t6, ($sp) \n\
ddivu $zero, $t6, $t7 \n\
bnez $t7, 1f \n\
nop \n\
break 7 \n\
1: \n\
mfhi $v0 \n\
dsll32 $v1, $v0, 0 \n\
dsra32 $v1, $v1, 0 \n\
jr $ra \n\
dsra32 $v0, $v0, 0 \n\
.end __umoddi3 \n\
.size __umoddi3, . - __umoddi3 \n\
\n\
.global __udivdi3 \n\
__udivdi3: \n\
.type __udivdi3, @function \n\
.ent __udivdi3 \n\
sw $a0, ($sp) \n\
sw $a1, 4($sp) \n\
sw $a2, 8($sp) \n\
sw $a3, 0xc($sp) \n\
ld $t7, 8($sp) \n\
ld $t6, ($sp) \n\
ddivu $zero, $t6, $t7 \n\
bnez $t7, 1f \n\
nop \n\
break 7 \n\
1: \n\
mflo $v0 \n\
dsll32 $v1, $v0, 0 \n\
dsra32 $v1, $v1, 0 \n\
jr $ra \n\
dsra32 $v0, $v0, 0 \n\
.end __udivdi3 \n\
.size __udivdi3, . - __udivdi3 \n\
\n\
.global __moddi3 \n\
__moddi3: \n\
.type __moddi3, @function \n\
.ent __moddi3 \n\
sw $a0, ($sp) \n\
sw $a1, 4($sp) \n\
sw $a2, 8($sp) \n\
sw $a3, 0xc($sp) \n\
ld $t7, 8($sp) \n\
ld $t6, ($sp) \n\
ddivu $zero, $t6, $t7 \n\
bnez $t7, 1f \n\
nop \n\
break 7 \n\
1: \n\
mfhi $v0 \n\
dsll32 $v1, $v0, 0 \n\
dsra32 $v1, $v1, 0 \n\
jr $ra \n\
dsra32 $v0, $v0, 0 \n\
.end __moddi3 \n\
.size __moddi3, . - __moddi3 \n\
\n\
.global __divdi3 \n\
__divdi3: \n\
.type __divdi3, @function \n\
.ent __divdi3 \n\
sw $a0, ($sp) \n\
sw $a1, 4($sp) \n\
sw $a2, 8($sp) \n\
sw $a3, 0xc($sp) \n\
ld $t7, 8($sp) \n\
ld $t6, ($sp) \n\
ddiv $zero, $t6, $t7 \n\
nop \n\
bnez $t7, 1f \n\
nop \n\
break 7 \n\
1: \n\
daddiu $at, $zero, -1 \n\
bne $t7, $at, 2f \n\
daddiu $at, $zero, 1 \n\
dsll32 $at, $at, 0x1f \n\
bne $t6, $at, 2f \n\
nop \n\
break 6 \n\
2: \n\
mflo $v0 \n\
dsll32 $v1, $v0, 0 \n\
dsra32 $v1, $v1, 0 \n\
jr $ra \n\
dsra32 $v0, $v0, 0 \n\
.end __divdi3 \n\
.size __divdi3, . - __divdi3 \n\
\n\
.set pop \n\
\n");
+4
View File
@@ -1,6 +1,10 @@
#include "PR/ultratypes.h"
#include "libc/math.h"
#ifdef COMPILER_GCC
#include "src/libultra/gcc_fix/sqrtf.c.inc"
#endif
f32 guSqrtf(f32 value) {
return sqrtf(value);
}
+8
View File
@@ -365,6 +365,14 @@ void Option_Setup(void) {
bool playedExpertMode;
s32 i;
#if MODS_LEVEL_SELECT == 1
for (i = 0; i < PLANET_MAX; i++) {
gSaveFile.save.data.planet[i].expertClear = 1;
gSaveFile.save.data.planet[i].normalClear = 1;
gSaveFile.save.data.planet[i].played = 1;
}
Save_Write();
#endif
gVIsPerFrame = 2;
sOptionCardList[0].unk_00.unk_08 = D_OPT_8003B50;
+4
View File
@@ -241,6 +241,8 @@ void Fault_ThreadEntry(void* arg0) {
func_8000762C(300, 10, "-");
gControllerPlugged[0] = 1;
#if 1 // Turn this off for instant crash debugger (no button combination needed)
while (var_s5 == 0) {
osSendMesg(&gSerialThreadMsgQueue, (OSMesg) SI_READ_CONTROLLER, OS_MESG_PRI_NORMAL);
osRecvMesg(&gControllerMsgQueue, NULL, OS_MESG_BLOCK);
@@ -312,6 +314,8 @@ void Fault_ThreadEntry(void* arg0) {
var_s0 = 0;
}
}
#endif
func_80007910(sp40);
while (1) {
;