diff --git a/Makefile b/Makefile index d045b818..d820ec95 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ COMPARE ?= 1 FIXUPS ?= 0 +MODERN_GCC ?= 0 ifneq ($(FIXUPS),0) COMPARE := 0 @@ -20,6 +21,12 @@ else $(error Invalid Target) endif +ifneq ($(MODERN_GCC),0) +COMPILER := modern_gcc +COMPARE := 0 +FIXUPS := 0 +endif + BASE_DIR := extracted/$(VERSION)/$(TARGET) BASE_AR := base/$(VERSION)/$(TARGET).a BUILD_ROOT := build @@ -43,6 +50,8 @@ ifeq ($(COMPILER),gcc) -include makefiles/gcc.mk else ifeq ($(COMPILER),ido) -include makefiles/ido.mk +else ifeq ($(COMPILER),modern_gcc) +-include makefiles/modern_gcc.mk else $(error Invalid Compiler) endif diff --git a/README.md b/README.md index 8fa9b97e..78714d46 100644 --- a/README.md +++ b/README.md @@ -70,3 +70,9 @@ If building for use with modern linkers, than you can use `FIXUPS=1` like the th - `make VERSION=L TARGET=libgultra_rom FIXUPS=1` note that running with `FIXUPS=1` will automatically set `COMPARE=0`. + +It is also possible to build archives using modern gcc by using `MODERN_GCC=1` like the following: + +- `make VERSION=L TARGET=libgultra_rom MODERN_GCC=1` + +note that running with `MODERN_GCC=1` will automatically set `COMPARE=0` and `FIXUPS=0`. diff --git a/include/PR/os_libc.h b/include/PR/os_libc.h index 35d0e8e6..98624ad0 100644 --- a/include/PR/os_libc.h +++ b/include/PR/os_libc.h @@ -80,10 +80,15 @@ extern "C" { /* byte string operations */ - +#ifndef MODERN_CC extern void bcopy(const void *, void *, int); extern int bcmp(const void *, const void *, int); extern void bzero(void *, int); +#else +extern void bcopy(const void *, void *, size_t); +extern int bcmp(const void *, const void *, size_t); +extern void bzero(void *, size_t); +#endif /* Printf */ diff --git a/include/modern_gcc/math.h b/include/modern_gcc/math.h new file mode 100644 index 00000000..3e93ceb1 --- /dev/null +++ b/include/modern_gcc/math.h @@ -0,0 +1 @@ +// Nothing needed here diff --git a/include/modern_gcc/memory.h b/include/modern_gcc/memory.h new file mode 100644 index 00000000..edfff5e7 --- /dev/null +++ b/include/modern_gcc/memory.h @@ -0,0 +1,23 @@ +#ifndef _MEMORY_H +#define _MEMORY_H +/* + memory.h +*/ + +#ifndef _SIZE_T_DEF +#define _SIZE_T_DEF +typedef unsigned size_t; +#endif + +void *memccpy(void *,void *,int,size_t); +void *memchr(void *,int,size_t); +int memcmp(const void *,const void *,size_t); +void *memcpy(void *,const void *,size_t); +int memicmp(void *,void *,size_t); +void *memmove(void *,void *,size_t); +void *memset(void *,int,size_t); + +void movmem(void *,void *,unsigned); +void setmem(void *,unsigned,int); + +#endif diff --git a/include/modern_gcc/sgidefs.h b/include/modern_gcc/sgidefs.h new file mode 100644 index 00000000..56567e88 --- /dev/null +++ b/include/modern_gcc/sgidefs.h @@ -0,0 +1,44 @@ +/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ralf Baechle . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _SGIDEFS_H +#define _SGIDEFS_H 1 + +/* + * Definitions for the ISA level + */ +#define _MIPS_ISA_MIPS1 1 +#define _MIPS_ISA_MIPS2 2 +#define _MIPS_ISA_MIPS3 3 +#define _MIPS_ISA_MIPS4 4 +#define _MIPS_ISA_MIPS5 5 + +/* + * Subprogram calling convention + * + * At the moment only _MIPS_SIM_ABI32 is in use. This will change rsn. + * Until GCC 2.8.0 is released don't rely on this definitions because the + * 64bit code is essentially using the 32bit interface model just with + * 64bit registers. + */ +#define _MIPS_SIM_ABI32 1 +#define _MIPS_SIM_NABI32 2 +#define _MIPS_SIM_ABI64 3 + +#endif /* sgidefs.h */ diff --git a/include/modern_gcc/stdarg.h b/include/modern_gcc/stdarg.h new file mode 100644 index 00000000..1f36b0a8 --- /dev/null +++ b/include/modern_gcc/stdarg.h @@ -0,0 +1,9 @@ +#ifndef _STDARG_H +#define _STDARG_H + +#define va_list __builtin_va_list +#define va_start __builtin_va_start +#define va_arg __builtin_va_arg +#define va_end __builtin_va_end + +#endif diff --git a/include/modern_gcc/stdio.h b/include/modern_gcc/stdio.h new file mode 100644 index 00000000..3e93ceb1 --- /dev/null +++ b/include/modern_gcc/stdio.h @@ -0,0 +1 @@ +// Nothing needed here diff --git a/include/modern_gcc/stdlib.h b/include/modern_gcc/stdlib.h new file mode 100644 index 00000000..98f8a2e1 --- /dev/null +++ b/include/modern_gcc/stdlib.h @@ -0,0 +1,81 @@ +#ifndef _STDLIB_H +#define _STDLIB_H +/* + stdlib.h +*/ + +#ifndef _SIZE_T_DEF +#define _SIZE_T_DEF +typedef unsigned size_t; +#endif + +#ifndef _DIV_T_DEF +#define _DIV_T_DEF +typedef struct DIV_T { + int quot; + int rem; +} div_t; +#endif + +#ifndef _LDIV_T_DEF +#define _LDIV_T_DEF +typedef struct LDIV_T { + long quot; + long rem; +} ldiv_t; +#endif + +#ifndef _LLDIV_T_DEF +#define _LLDIV_T_DEF +typedef struct lldiv_t +{ + long long quot; + long long rem; +} lldiv_t; +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#define _max(a,b) (((a) > (b)) ? (a) : (b)) +#define _min(a,b) (((a) < (b)) ? (a) : (b)) + +#define RAND_MAX 32767 + +int rand(void); +void srand(unsigned); + +int abs(int); +long labs(long); + +div_t div(int,int); +ldiv_t ldiv(long,long); +lldiv_t lldiv(long long, long long); + +int atoi(const char *); +long atol(const char *); + +long strtol(const char *,char **,int); +unsigned long strtoul(const char *,char **,int); + +char *itoa(int,char *,int); +char *ltoa(long,char *,int); +char *ultoa(unsigned long,char *,int); + +double atof(const char *); +double strtod(const char *,char **); + +void qsort(void *,size_t,size_t,int (*)(const void *,const void *)); +void *bsearch(const void *,const void *,size_t,size_t,int (*)(const void *,const void *)); + +void *malloc(size_t); +void *calloc(size_t,size_t); +void *realloc(void *,size_t); +void free(void *); + +void exit(int); + +void abort(void); + +#endif diff --git a/include/modern_gcc/string.h b/include/modern_gcc/string.h new file mode 100644 index 00000000..d82e1f10 --- /dev/null +++ b/include/modern_gcc/string.h @@ -0,0 +1,42 @@ +#ifndef _STRING_H +#define _STRING_H +/* + string.h +*/ + +#ifndef _SIZE_T_DEF +#define _SIZE_T_DEF +typedef unsigned size_t; +#endif + +#include "memory.h" + +char *stpcpy(char *,const char *); +char *strcat(char *,const char *); +char *strchr(const char *,int); +int strcmp(const char *,const char *); +char *strcpy(char *,const char *); +size_t strcspn(const char *,const char *); +char *strdup(const char *); +char *strerror(int); +int stricmp(const char *,const char *); +size_t strlen(const char *); +char *strlwr(char *); +char *strncat(char *,const char *,size_t); +int strncmp(const char *,const char *,size_t); +char *strncpy(char *,const char *,size_t); +int strnicmp(const char *,const char *,size_t); +char *strnset(char *,int,size_t); +char *strpbrk(const char *,const char *); +char *strrchr(const char *,int); +char *strrev(char *); +char *strset(char *,int); +size_t strspn(const char *,const char *); +char *strstr(const char *,const char *); +char *strtok(char *,const char *); +char *strupr(char *); + +#define strcmpi(s1,s2) stricmp(s1,s2) +#define strncmpi(s1,s2,n) strnicmp(s1,s2,n) + +#endif diff --git a/makefiles/modern_gcc.mk b/makefiles/modern_gcc.mk new file mode 100644 index 00000000..afcf5e28 --- /dev/null +++ b/makefiles/modern_gcc.mk @@ -0,0 +1,21 @@ + +COMPILER_DIR := $(dir $(which $(CROSS)gcc)) +AS := $(CROSS)gcc -x assembler-with-cpp +CC := $(CROSS)gcc +AR_OLD := $(CROSS)ar + +WARNINGS := -Wall -Wextra -Wno-format-security -Wno-unused-function -Wno-unused-parameter -Wno-unused-variable -Wno-builtin-declaration-mismatch +WARNINGS += -Wno-int-conversion -Wno-incompatible-pointer-types -Wno-implicit-function-declaration # TODO: Try adjusting code to remove these +CFLAGS := -G 0 -c -nostdinc -march=vr4300 -mfix4300 -mabi=32 -mno-abicalls -mdivide-breaks -fno-PIC -fno-common -ffreestanding -fbuiltin -fno-builtin-sinf -fno-builtin-cosf -funsigned-char $(WARNINGS) +CFLAGS += -fno-strict-aliasing # TODO: Try adjusting code to remove this +ASFLAGS := -w -nostdinc -c -G 0 -march=vr4300 -mgp32 -mfp32 -DMIPSEB -D_LANGUAGE_ASSEMBLY -D_MIPS_SIM=1 -D_ULTRA64 +CPPFLAGS = -DMODERN_CC -D_MIPS_SZLONG=32 -D__USE_ISOC99 $(GBIDEFINE) $(VERSION_DEFINE) $(DEBUGFLAG) +IINC = -I . -I $(WORKING_DIR)/include -I $(WORKING_DIR)/include/modern_gcc -I $(WORKING_DIR)/include/PR +MIPS_VERSION := -mips3 +ASOPTFLAGS := + +ifeq ($(findstring _d,$(TARGET)),_d) +OPTFLAGS := -Og -ggdb3 -ffast-math -fno-unsafe-math-optimizations +else +OPTFLAGS := -Os -ggdb3 -ffast-math -fno-unsafe-math-optimizations +endif diff --git a/src/os/exceptasm.s b/src/os/exceptasm.s index f1e65874..919482e7 100644 --- a/src/os/exceptasm.s +++ b/src/os/exceptasm.s @@ -1,3 +1,7 @@ +#ifdef MODERN_CC +.set gp=64 +#endif + #include "PR/R4300.h" #include "sys/asm.h" #include "sys/regdef.h" diff --git a/src/os/getfpccsr.s b/src/os/getfpccsr.s index 159bc4aa..f51b1d0f 100644 --- a/src/os/getfpccsr.s +++ b/src/os/getfpccsr.s @@ -6,4 +6,8 @@ LEAF(__osGetFpcCsr) CFC1( v0, fcr31) jr ra +#ifndef MODERN_CC END(__osGetSR) # @bug: Should be __osGetFpcCsr +#else +END(__osGetFpcCsr) +#endif diff --git a/src/os/setfpccsr.s b/src/os/setfpccsr.s index 4b8f0e6e..f36e5b8c 100644 --- a/src/os/setfpccsr.s +++ b/src/os/setfpccsr.s @@ -7,4 +7,8 @@ LEAF(__osSetFpcCsr) CFC1( v0, fcr31) CTC1( a0, fcr31) jr ra +#ifndef MODERN_CC END(__osSetSR) # @bug: Should be __osSetFpcCsr +#else +END(__osSetFpcCsr) +#endif