1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-02-09 14:06:54 +00:00

GCC support.

This commit is contained in:
ProjectRevoTPP 2021-12-02 21:00:42 -05:00
parent 4390dd74b6
commit 45ccb7fd05
7 changed files with 237 additions and 14 deletions

View file

@ -8,10 +8,23 @@ COMPARE ?= 1
NON_MATCHING ?= 0
# If ORIG_COMPILER is 1, compile with QEMU_IRIX and the original compiler
ORIG_COMPILER ?= 0
# If COMPILER is GCC, compile with GCC instead of IDO.
COMPILER ?= ido
# Convert text in source files (.c) to EUC-JP before compilation, but only on GCC.
# This is required in order to preserve debug print functionality on GCC since it
# doesn't seem to recognize EUC-JP marked files without doing this beforehand.
CONV_SOURCE_TEXT ?= 1
# 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)
NON_MATCHING := 1
CPPFLAGS := -DCOMPILER_GCC
endif
ifeq ($(NON_MATCHING),1)
CFLAGS := -DNON_MATCHING
CPPFLAGS := -DNON_MATCHING
CFLAGS += -DNON_MATCHING
CPPFLAGS += -DNON_MATCHING
COMPARE := 0
endif
@ -41,8 +54,22 @@ else
$(error Please install or build mips-linux-gnu)
endif
CC := tools/ido_recomp/$(DETECTED_OS)/7.1/cc
CC_OLD := tools/ido_recomp/$(DETECTED_OS)/5.3/cc
# Detect compiler and set variables appropriately.
ifeq ($(COMPILER),gcc)
ifeq ($(CONV_SOURCE_TEXT),1)
CC = iconv -f UTF-8 -t EUC-JP $< | mips-linux-gnu-gcc -x c -
else
CC = mips-linux-gnu-gcc $<
endif
CC_OLD := $(CC)
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
# if ORIG_COMPILER is 1, check that either QEMU_IRIX is set or qemu-irix package installed
ifeq ($(ORIG_COMPILER),1)
@ -77,10 +104,17 @@ ZAPD := tools/ZAPD/ZAPD.out
OPTFLAGS := -O2
ASFLAGS := -march=vr4300 -32 -Iinclude
MIPS_VERSION := -mips2
# 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 -Xfullwarn -Xcpluscomm $(INC) -Wab,-r4300_mul -woff 649,838,712
ifeq ($(COMPILER),gcc)
CFLAGS += -c -G 0 -nostdinc -Iinclude -Isrc -Iassets -Ibuild -I. -DNON_MATCHING=1 -DMODDING=1 -DNORMAL_GAMEPLAY=1 -DAVOID_UB=1 -mno-shared -march=vr4300 -mfix4300 -mabi=32 -mhard-float -mdivide-breaks -fno-stack-protector -fno-common -fno-zero-initialized-in-bss -mno-abicalls -fno-strict-aliasing -fno-inline-functions -fno-inline-small-functions -fno-toplevel-reorder -ffreestanding -fwrapv $(CHECK_WARNINGS) -g -mno-explicit-relocs -mno-split-addresses -funsigned-char
MIPS_VERSION := -mips3
PIPEIN =
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 -Xfullwarn -Xcpluscomm $(INC) -Wab,-r4300_mul -woff 649,838,712
MIPS_VERSION := -mips2
PIPEIN = $<
endif
ifeq ($(shell getconf LONG_BIT), 32)
# Work around memory allocation bug in QEMU
@ -126,6 +160,7 @@ TEXTURE_FILES_OUT := $(foreach f,$(TEXTURE_FILES_PNG:.png=.inc.c),build/$f) \
# create build directories
$(shell mkdir -p build/baserom build/assets/text $(foreach dir,$(SRC_DIRS) $(ASM_DIRS) $(ASSET_BIN_DIRS),build/$(dir)))
ifeq ($(COMPILER),ido)
build/src/code/fault.o: CFLAGS += -trapuv
build/src/code/fault.o: OPTFLAGS := -O2 -g3
build/src/code/fault_drawer.o: CFLAGS += -trapuv
@ -162,6 +197,7 @@ build/src/code/%.o: CC := python3 tools/asm_processor/build.py $(CC) -- $(AS) $(
build/src/overlays/%.o: CC := python3 tools/asm_processor/build.py $(CC) -- $(AS) $(ASFLAGS) --
build/assets/%.o: CC := python3 tools/asm_processor/build.py $(CC) -- $(AS) $(ASFLAGS) --
endif
#### Main Targets ###
@ -231,7 +267,7 @@ build/assets/text/nes_message_data_static.o: build/assets/text/message_data.enc.
build/assets/text/staff_message_data_static.o: build/assets/text/message_data_staff.enc.h
build/assets/%.o: assets/%.c
$(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $<
$(CC) -c $(CFLAGS) -I $(<D) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $(PIPEIN)
$(OBJCOPY) -O binary $@ $@.bin
build/dmadata_table_spec.h: build/$(SPEC)
@ -241,25 +277,25 @@ build/src/boot/z_std_dma.o: build/dmadata_table_spec.h
build/src/dmadata/dmadata.o: build/dmadata_table_spec.h
build/src/overlays/%.o: src/overlays/%.c
$(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $<
$(CC) -c $(CFLAGS) -I $(<D) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $(PIPEIN)
$(CC_CHECK) $<
$(ZAPD) bovl -eh -i $@ -cfg $< --outputpath $(@D)/$(notdir $(@D))_reloc.s
$(ZAPD) bovl -eh -i $@ -cfg $< --outputpath $(@D)/$(notdir $(@D))_reloc.s --gcc-compat
-test -f $(@D)/$(notdir $(@D))_reloc.s && $(AS) $(ASFLAGS) $(@D)/$(notdir $(@D))_reloc.s -o $(@D)/$(notdir $(@D))_reloc.o
@$(OBJDUMP) -d $@ > $(@:.o=.s)
build/src/%.o: src/%.c
$(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $<
$(CC) -c $(CFLAGS) -I $(<D) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $(PIPEIN)
$(CC_CHECK) $<
@$(OBJDUMP) -d $@ > $(@:.o=.s)
build/src/libultra/libc/ll.o: src/libultra/libc/ll.c
$(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $<
$(CC) -c $(CFLAGS) -I $(<D) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $(PIPEIN)
$(CC_CHECK) $<
python3 tools/set_o32abi_bit.py $@
@$(OBJDUMP) -d $@ > $(@:.o=.s)
build/src/libultra/libc/llcvt.o: src/libultra/libc/llcvt.c
$(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $<
$(CC) -c $(CFLAGS) -I $(<D) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $(PIPEIN)
$(CC_CHECK) $<
python3 tools/set_o32abi_bit.py $@
@$(OBJDUMP) -d $@ > $(@:.o=.s)

103
asm/llmuldiv_gcc.s Normal file
View file

@ -0,0 +1,103 @@
.include "macro.inc"
# assembler directives
.set noat # allow manual use of $at
.set noreorder # don't insert nops after branches
.set gp=64 # allow use of 64-bit general purpose registers
.section .text
.balign 16
/* Copied from Super Mario 64 decomp project */
/* -------------------------------------------------------------------------------------- */
/* need to asm these functions because lib32gcc-7-dev-mips-cross does not exist so we */
/* cannot naturally link a libgcc variant for this target given this architecture and */
/* compiler. Until we have a good workaround with a gcc target that doesn't involve */
/* assuming a 32-bit to 64-bit change, we have to encode these functions as raw assembly */
/* for it to compile. */
/* -------------------------------------------------------------------------------------- */
/* TODO: Is there a non-insane way to fix this hack that doesn't involve the user compiling */
/* a library themselves? */
glabel __umoddi3
sw $a0, ($sp)
sw $a1, 4($sp)
sw $a2, 8($sp)
sw $a3, 0xc($sp)
ld $t7, 8($sp)
ld $t6, ($sp)
ddivu $zero, $t6, $t7
bnez $t7, .L80324144
nop
break 7
.L80324144:
mfhi $v0
dsll32 $v1, $v0, 0
dsra32 $v1, $v1, 0
jr $ra
dsra32 $v0, $v0, 0
glabel __udivdi3
sw $a0, ($sp)
sw $a1, 4($sp)
sw $a2, 8($sp)
sw $a3, 0xc($sp)
ld $t7, 8($sp)
ld $t6, ($sp)
ddivu $zero, $t6, $t7
bnez $t7, .L80324180
nop
break 7
.L80324180:
mflo $v0
dsll32 $v1, $v0, 0
dsra32 $v1, $v1, 0
jr $ra
dsra32 $v0, $v0, 0
glabel __moddi3
sw $a0, ($sp)
sw $a1, 4($sp)
sw $a2, 8($sp)
sw $a3, 0xc($sp)
ld $t7, 8($sp)
ld $t6, ($sp)
ddivu $zero, $t6, $t7
bnez $t7, .L803241E8
nop
break 7
.L803241E8:
mfhi $v0
dsll32 $v1, $v0, 0
dsra32 $v1, $v1, 0
jr $ra
dsra32 $v0, $v0, 0
glabel __divdi3
sw $a0, ($sp)
sw $a1, 4($sp)
sw $a2, 8($sp)
sw $a3, 0xc($sp)
ld $t7, 8($sp)
ld $t6, ($sp)
ddiv $zero, $t6, $t7
nop
bnez $t7, .L80324228
nop
break 7
.L80324228:
daddiu $at, $zero, -1
bne $t7, $at, .L80324244
daddiu $at, $zero, 1
dsll32 $at, $at, 0x1f
bne $t6, $at, .L80324244
nop
break 6
.L80324244:
mflo $v0
dsll32 $v1, $v0, 0
dsra32 $v1, $v1, 0
jr $ra
dsra32 $v0, $v0, 0

View file

@ -4,7 +4,14 @@
#include "z64.h"
f32 fabsf(f32 f);
#ifndef __sgi
#define fabsf __builtin_fabsf
f32 __floatundisf(u32 c);
f64 __floatundidf(u32 c);
unsigned long __udivdi3(unsigned long a, unsigned long b);
#else
#pragma intrinsic(fabsf)
#endif
f32 sqrtf(f32 f);
#pragma intrinsic(sqrtf)
f64 sqrt(f64 d);

4
spec
View file

@ -109,6 +109,10 @@ beginseg
include "build/src/libultra/os/gethwintrroutine.o"
include "build/asm/__osSetWatchLo.o"
include "build/data/rsp_boot.text.o"
#ifdef COMPILER_GCC
include "build/asm/llmuldiv_gcc.o"
include "build/src/boot/missing_gcc_functions.o"
#endif
endseg
beginseg

View file

@ -0,0 +1,68 @@
#include "global.h"
// Define functions needed for the GCC build here.
// Self-hosted memcmp.
int memcmp(void *s1, const void *s2, size_t n) {
u8 *m1 = (u8 *)s1;
u8 *m2 = (u8 *)s2;
int i;
for (i = 0; i < n; i++) {
if (m1[i] < m2[i]) {
return -1;
} else if (m1[i] > m2[i]) {
return 1;
}
}
return 0;
}
void *memset(void *str, int c, size_t n) {
u8 *m1 = (u8 *)str;
int i;
for(i = 0; i < n; i++) {
m1[i] = c;
}
return str;
}
// These functions convert c to an unsigned integer, rounding toward zero. Negative values
// all become zero.
u32 __fixunssfdi(f32 a) {
if (a < 0.0f)
a = 0.0f;
return (u32)a;
}
u32 __fixunsdfdi(f64 a) {
if (a < 0.0)
a = 0.0;
return (u32)a;
}
// These functions convert c to a signed integer, rounding toward zero.
s32 __fixsfdi(f32 c) {
return (s32)c;
}
s32 __fixdfdi(f64 c) {
return (s32)c;
}
// These functions convert c, a signed integer, to floating point.
f32 __floatdisf(s32 c) {
return (f32)c;
}
f64 __floatdidf(s32 c) {
return (f64)c;
}
// These functions convert c, an unsigned integer, to floating point.
f32 __floatundisf(u32 c) {
return (f32)c;
}
f64 __floatundidf(u32 c) {
return (f64)c;
}

View file

@ -1021,7 +1021,9 @@ void* AudioHeap_AllocPermanent(s32 tableType, s32 id, u32 size) {
gAudioContext.permanentCache[index].size = size;
//! @bug UB: missing return. "ret" is in v0 at this point, but doing an
// explicit return uses an additional register.
// return ret;
#ifdef AVOID_UB
return ret;
#endif
}
void* AudioHeap_AllocSampleCache(u32 size, s32 fontId, void* sampleAddr, s8 medium, s32 cache) {

View file

@ -35,6 +35,9 @@ const ActorInit En_Tana_InitVars = {
static const char* sShelfTypes[] = {
"木の棚", // "Wooden Shelves"
"石の棚", // "Stone Shelves"
#ifdef AVOID_UB
"",
#endif
};
static const ActorFunc sDrawFuncs[] = {