diff --git a/configure.py b/configure.py index 7a8e81cf..e21823bd 100644 --- a/configure.py +++ b/configure.py @@ -172,6 +172,10 @@ # Use for any additional files that should cause a re-configure when modified config.reconfig_deps = [] +# Optional numeric ID for decomp.me preset +# Can be overridden in libraries or objects +config.scratch_preset_id = None + # Base flags, common to most GC/Wii games. # Generally leave untouched, with overrides added below. cflags_base = [ @@ -181,7 +185,7 @@ "-enum int", "-fp hardware", "-Cpp_exceptions off", - "-O4,s", + "-O4,p", "-inline auto", '-pragma "cats off"', '-pragma "warn_notinlined off"', @@ -190,7 +194,7 @@ "-RTTI off", "-fp_contract on", "-str reuse", - "-multibyte", # For Wii compilers, replace with `-enc SJIS` + "-enc SJIS", "-i include", f"-i build/{config.version}/include", f"-DVERSION={version_num}" @@ -358,13 +362,8 @@ "-gccinc", "-common off", "-inline auto", -] - -# REL flags -cflags_rel = [ - *cflags_base, - "-sdata 0", - "-sdata2 0", + "-i libs/Runtime/include", + "-i libs/MSL_C/include" ] config.linker_version = "GC/3.0a5" diff --git a/include/Game/LiveActor/LiveActor.hpp b/include/Game/LiveActor/LiveActor.hpp index 21103523..ef03b80a 100644 --- a/include/Game/LiveActor/LiveActor.hpp +++ b/include/Game/LiveActor/LiveActor.hpp @@ -27,7 +27,7 @@ class LiveActor : public NameObj { /// @param pName The new name assigned to the LiveActor. LiveActor(const char *pName); - virtual inline ~LiveActor() {} + virtual inline ~LiveActor(); virtual void init(JMapInfoIter const &); virtual void movement(); diff --git a/src/Game/MapObj/BigFan.cpp b/src/Game/MapObj/BigFan.cpp index 6b596d45..17a80b12 100644 --- a/src/Game/MapObj/BigFan.cpp +++ b/src/Game/MapObj/BigFan.cpp @@ -176,4 +176,4 @@ namespace NrvBigFan { BigFan::~BigFan() { -} \ No newline at end of file +} diff --git a/src/Runtime/GCN_mem_alloc.c b/src/Runtime/GCN_mem_alloc.c new file mode 100644 index 00000000..d605b856 --- /dev/null +++ b/src/Runtime/GCN_mem_alloc.c @@ -0,0 +1,42 @@ +extern void OSReport(const char *, ...); +extern void* OSGetArenaLo(); +extern void* OSGetArenaHi(); +extern void* OSInitAlloc(void *, void *, int); +extern volatile int __OSCurrHeap; + +#define OSRoundUp32B(x) (((unsigned int)(x) + 32 - 1) & ~(32 - 1)) +#define OSRoundDown32B(x) (((unsigned int)(x)) & ~(32 - 1)) + +static void InitDefaultHeap() +{ + void* arenaLo; + void* arenaHi; + + OSReport("GCN_Mem_Alloc.c : InitDefaultHeap. No Heap Available\n"); + OSReport("Metrowerks CW runtime library initializing default heap\n"); + + arenaLo = OSGetArenaLo(); + arenaHi = OSGetArenaHi(); + + arenaLo = OSInitAlloc(arenaLo, arenaHi, 1); + OSSetArenaLo(arenaLo); + + arenaLo = (void*)OSRoundUp32B(arenaLo); + arenaHi = (void*)OSRoundDown32B(arenaHi); + + OSSetCurrentHeap(OSCreateHeap(arenaLo, arenaHi)); + OSSetArenaLo(arenaLo = arenaHi); +} + +// unused +void __sys_alloc() +{ +} + +__declspec(weak) extern void __sys_free(void* ptr) +{ + if (__OSCurrHeap == -1) { + InitDefaultHeap(); + } + OSFreeToHeap(__OSCurrHeap, ptr); +} diff --git a/src/Runtime/Gecko_ExceptionPPC.cpp b/src/Runtime/Gecko_ExceptionPPC.cpp new file mode 100644 index 00000000..c2eecbdd --- /dev/null +++ b/src/Runtime/Gecko_ExceptionPPC.cpp @@ -0,0 +1,37 @@ +#include + +typedef struct ProcessInfo { + __eti_init_info* exception_info; + char* TOC; + int active; +} ProcessInfo; + +static ProcessInfo fragmentinfo[1]; + +int __register_fragment(struct __eti_init_info *pInfo, char *pTOC) { + ProcessInfo* info; + int i; + + for (i = 0, info = fragmentinfo; i < 1; ++i, ++info) { + if (info->active == 0) { + info->exception_info = pInfo; + info->TOC = pTOC; + info->active = 1; + return i; + } + } + + + return -1; +} + +void __unregister_fragment(int id) { + ProcessInfo* info; + + if (id >= 0 && id < 1) { + info = &fragmentinfo[id]; + info->exception_info = 0; + info->TOC = 0; + info->active = 0; + } +} \ No newline at end of file diff --git a/src/Runtime/NMWException.cpp b/src/Runtime/NMWException.cpp new file mode 100644 index 00000000..5e543f1f --- /dev/null +++ b/src/Runtime/NMWException.cpp @@ -0,0 +1,92 @@ +#include +#include + +class __partial_array_destructor { +public: + void* mArrayStart; // 0x0 + size_t mElemSize; // 0x4 + size_t mArraySize; // 0x8 + ctor_dtor_ptr mDtorPtr; // 0xC + size_t mCurElement; // 0x10 + + __partial_array_destructor(void *arr, unsigned int size, unsigned int count, ctor_dtor_ptr ptr) { + mArrayStart = arr; + mElemSize = size; + mArraySize = count; + mDtorPtr = ptr; + mCurElement = mArraySize; + } + + ~__partial_array_destructor() { + if (mCurElement < mArraySize && mDtorPtr) { + for (char* cur = (char*)mArrayStart + (mElemSize * mCurElement); mCurElement > 0; mCurElement--) { + cur -= mElemSize; + ((void (*)(void *, short))mDtorPtr)(cur,-1); + } + } + } +}; + +extern "C" { + +void __construct_array(void *pBlock, ctor_dtor_ptr ctor, ctor_dtor_ptr dtor, size_t size, size_t n) { + __partial_array_destructor pad(pBlock, size, n, dtor); + + char* p = (char*)pBlock; + for (pad.mCurElement = 0; pad.mCurElement < n; p += size, pad.mCurElement++) { + ((void (*)(void *, short))ctor)(p,1); + } +} + +void *__construct_new_array(void *block, ctor_dtor_ptr ctor, ctor_dtor_ptr dtor, size_t size, size_t n) { + char *ptr = (char *)block; + + if (ptr != 0){ + *(size_t *)ptr = size; + *(size_t *)(ptr + 4) = n; + ptr += 0x10; + + if (ctor) { + + __partial_array_destructor pad(ptr, size, n, dtor); + + char* p; + for (pad.mCurElement = 0, p = ptr; pad.mCurElement < n; pad.mCurElement++, p += size) { + ((void (*)(void *, short))ctor)(p,1); + } + } + } + return ptr; +} + +void __destroy_arr(void *pArraySource, ctor_dtor_ptr dtor, size_t size, size_t num) { + char* cur; + + for (cur = (char*)pArraySource + (size * num); num > 0; num--) { + cur -= size; + ((void (*)(void *, short))dtor)(cur,-1); + } +} + +void __destroy_new_array(void *pArraySource, ctor_dtor_ptr dtor) { + if (pArraySource != 0) { + if (dtor != 0) { + size_t i, objs, obj_size; + char* cur; + + // why are the 8 and 12 important to match? + obj_size = *(size_t*)((char*)pArraySource - 2 * 8); + objs = *(size_t*)((char *)pArraySource - 12); + cur = (char*)pArraySource + obj_size * objs; + + for (i = 0; i < objs; i++) { + cur -= obj_size; + ((void (*)(void *, short))dtor)(cur,-1); + } + } + + ::operator delete[] ((char *)pArraySource-2*8); + } +} + +} \ No newline at end of file diff --git a/src/Runtime/__init_cpp_exceptions.cpp b/src/Runtime/__init_cpp_exceptions.cpp new file mode 100644 index 00000000..3e1520d4 --- /dev/null +++ b/src/Runtime/__init_cpp_exceptions.cpp @@ -0,0 +1,36 @@ +#include <__ppc_eabi_linker.h> +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern void __init_cpp_exceptions(void); +extern void __fini_cpp_exceptions(void); + +#ifdef __cplusplus +} +#endif + +static int fragmentID = -2; + +void __init_cpp_exceptions(void) { + if (fragmentID == -2) { + register char *temp; + asm { + mr temp,r2 + } + + fragmentID = __register_fragment(_eti_init_info, (char*)temp); + } +} + +void __fini_cpp_exceptions(void) { + if (fragmentID != -2) { + __unregister_fragment(fragmentID); + fragmentID = -2; + } +} + +__declspec(section ".ctors") +extern void * const __init_cpp_exceptions_reference = __init_cpp_exceptions; \ No newline at end of file diff --git a/src/Runtime/__mem.c b/src/Runtime/__mem.c new file mode 100644 index 00000000..b2f67b3d --- /dev/null +++ b/src/Runtime/__mem.c @@ -0,0 +1,86 @@ +#include <__mem.h> + +void* memcpy(void *pDest, const void *pSrc, size_t len) { + const char *p; + char* q; + int rev = pDest < pSrc; + + if (!rev) { + for (p = (const char*)pSrc - 1, q = (char*)pDest - 1, len++; --len;) { + *++q = *++p; + } + } + else { + for (p = (const char*)pSrc + len, q = (char*)pDest + len, len++; --len;) { + *--q = *--p; + } + } + + return pDest; +} + +// I really wish I could tell you what's going on here but I can't +void __fill_mem(void *pDest, int val, unsigned long n) { + unsigned long v = (unsigned char) val; + unsigned long i; + + ((unsigned char*)pDest) = ((unsigned char*)pDest) - 1; + + if (n >= 32) { + i = (~(unsigned long)pDest) & 3; + + if (i) { + n -= i; + + do { + *++(((unsigned char*)pDest)) = v; + } + while (--i); + } + + if (v != 0) { + v |= v << 24 | v << 16 | v << 8; + } + + ((unsigned long*)pDest) = ((unsigned long*) (((unsigned char*)pDest) + 1)) - 1; + i = n >> 5; + + if (i != 0) { + do { + *++(((unsigned long*)pDest)) = v; + *++(((unsigned long*)pDest)) = v; + *++(((unsigned long*)pDest)) = v; + *++(((unsigned long*)pDest)) = v; + *++(((unsigned long*)pDest)) = v; + *++(((unsigned long*)pDest)) = v; + *++(((unsigned long*)pDest)) = v; + *++(((unsigned long*)pDest)) = v; + } + while (--i); + } + + i = (n & 31) >> 2; + + if (i) { + do { + *++(((unsigned long*)pDest)) = v; + } + while (--i); + } + + ((unsigned char*)pDest) = ((unsigned char*) (((unsigned long*)pDest) + 1)) - 1; + n &= 3; + } + + if (n) { + do { + *++(((unsigned char*)pDest)) = v; + } + while (--n); + } +} + +void* memset(void *pDest, int val, size_t num) { + __fill_mem(pDest, val, num); + return pDest; +} diff --git a/src/Runtime/__va_arg.c b/src/Runtime/__va_arg.c new file mode 100644 index 00000000..e5cae92a --- /dev/null +++ b/src/Runtime/__va_arg.c @@ -0,0 +1,63 @@ +typedef struct { + char gpr; + char fpr; + char reserved[2]; + char *input_arg_area; + char *reg_save_area; +} va_list[1]; + +typedef enum { + arg_ARGPOINTER, + arg_WORD, + arg_DOUBLEWORD, + arg_REAL, + arg_VECTOR +} _va_arg_type; + +#define ALIGN(addr,amount) (((unsigned int)(addr)+((amount)-1))&~((amount)-1)) + +void* __va_arg(va_list ap, _va_arg_type type) { + char* addr; + char* r = &(ap->gpr); + int rr = ap->gpr; + int max = 8; + int size = 4; + int inc = 1; + int even = 0; + int fpr_offset = 0; + int size_reg = 4; + + if (type == 3) { + r = &(ap->fpr); + rr = ap->fpr; + size = 8; + fpr_offset = 32; + size_reg = 8; + } + + if (type == 2) { + size = 8; + max = max - 1; + + if (rr & 1) { + even = 1; + } + + inc = 2; + } + + if (rr < max) { + rr += even; + addr = ap->reg_save_area + fpr_offset + (rr * size_reg); + *r = rr + inc; + } else { + *r = 8; + addr = ap->input_arg_area; + addr = (char*)ALIGN(addr, size); + ap->input_arg_area = addr + size; + } + if (type == 0) + addr = *((char**)addr); + + return addr; +} \ No newline at end of file diff --git a/src/Runtime/global_destructor_chain.c b/src/Runtime/global_destructor_chain.c new file mode 100644 index 00000000..a82743f6 --- /dev/null +++ b/src/Runtime/global_destructor_chain.c @@ -0,0 +1,31 @@ +typedef struct DestructorChain { + struct DestructorChain* next; + void* dtor; + void* obj; +} DestructorChain; + + +DestructorChain* __global_destructor_chain; + +void* __register_global_object(void *pObj, void *pDtor, void *pReg) { + DestructorChain* chain = (DestructorChain*)pReg; + chain->next = __global_destructor_chain; + chain->dtor = pDtor; + chain->obj = pObj; + __global_destructor_chain = (DestructorChain*)pReg; + return pObj; +} + +void __destroy_global_chain(void) { + DestructorChain* chain; + void* obj; + + while ((chain = __global_destructor_chain) != 0) { + __global_destructor_chain = chain->next; + obj = chain->obj; + (((void (*)(void *,short))chain->dtor)(obj,-1)); + } +} + +__declspec(section ".dtors") +extern void * const __destroy_global_chain_reference = __destroy_global_chain; \ No newline at end of file diff --git a/src/Runtime/ptmf.c b/src/Runtime/ptmf.c new file mode 100644 index 00000000..58d25427 --- /dev/null +++ b/src/Runtime/ptmf.c @@ -0,0 +1,58 @@ +typedef struct PTMF { + long this_delta; + long vtbl_offset; + union { + void *func_addr; + long ventry_offset; + } func_data; +} PTMF; + +asm long __ptmf_test(register PTMF *ptmf) { + nofralloc + lwz r5,PTMF.this_delta(r3) + lwz r6,PTMF.vtbl_offset(r3) + lwz r7,PTMF.func_data(r3) + li r3,1 + cmpwi cr0,r5,0 + cmpwi cr6,r6,0 + cmpwi cr7,r7,0 + bnelr cr0 + bnelr cr6 + bnelr cr7 + li r3,0 + blr +} + +asm long __ptmf_cmpr(register PTMF *ptmf1, register PTMF *ptmf2) { + nofralloc + lwz r5,PTMF.this_delta(r3) + lwz r6,PTMF.this_delta(r4) + lwz r7,PTMF.vtbl_offset(r3) + lwz r8,PTMF.vtbl_offset(r4) + lwz r9,PTMF.func_data(r3) + lwz r10,PTMF.func_data(r4) + li r3,1 + cmpw cr0,r5,r6 + cmpw cr6,r7,r8 + cmpw cr7,r9,r10 + bnelr cr0 + bnelr cr6 + bnelr cr7 + li r3,0 + blr +} + +asm void __ptmf_scall(...) { + nofralloc + lwz r0,PTMF.this_delta(r12) + lwz r11,PTMF.vtbl_offset(r12) + lwz r12,PTMF.func_data(r12) + add r3,r3,r0 + cmpwi cr0,r11,0 + blt cr0,@1 + lwzx r12,r3,r12 + lwzx r12,r12,r11 + +@1 mtctr r12 + bctr +} \ No newline at end of file diff --git a/src/Runtime/runtime.c b/src/Runtime/runtime.c new file mode 100644 index 00000000..6449bae0 --- /dev/null +++ b/src/Runtime/runtime.c @@ -0,0 +1,867 @@ +#ifdef __cplusplus +extern "C" { +#endif + +/* macros for GPR/FPR resting and saving */ +#define SAVE_FPR(reg) _savefpr_ ## reg +#define RESTORE_FPR(reg) _restfpr_ ## reg +#define SAVE_GPR(reg) _savegpr_ ## reg +#define RESTORE_GPR(reg) _restgpr_ ## reg +#define ENTRY_SAVE_FPR(reg) entry SAVE_FPR(reg) +#define ENTRY_RESTORE_FPR(reg) entry RESTORE_FPR(reg) +#define ENTRY_SAVE_GPR(reg) entry SAVE_GPR(reg) +#define ENTRY_RESTORE_GPR(reg) entry RESTORE_GPR(reg) +#define SAVE_FPR2(reg) _savef ## reg +#define RESTORE_FPR2(reg) _restf ## reg +#define ENTRY_SAVE_FPR2(reg) +#define ENTRY_RESTORE_FPR2(reg) + +#define save_restore_reg r11 + + +asm void __div2u(void); +asm void __div2i(void); +asm void __mod2u(void); +asm void __mod2i(void); +asm void __shl2i(void); +asm void __shr2u(void); +asm void __cvt_dbl_usll(void); +asm void __cvt_dbl_ull(void); + +void SAVE_FPR(14)(void); +void SAVE_FPR(15)(void); +void SAVE_FPR(16)(void); +void SAVE_FPR(17)(void); +void SAVE_FPR(18)(void); +void SAVE_FPR(19)(void); +void SAVE_FPR(20)(void); +void SAVE_FPR(21)(void); +void SAVE_FPR(22)(void); +void SAVE_FPR(23)(void); +void SAVE_FPR(24)(void); +void SAVE_FPR(25)(void); +void SAVE_FPR(26)(void); +void SAVE_FPR(27)(void); +void SAVE_FPR(28)(void); +void SAVE_FPR(29)(void); +void SAVE_FPR(30)(void); +void SAVE_FPR(31)(void); +void SAVE_FPR2(14)(void); +void SAVE_FPR2(15)(void); +void SAVE_FPR2(16)(void); +void SAVE_FPR2(17)(void); +void SAVE_FPR2(18)(void); +void SAVE_FPR2(19)(void); +void SAVE_FPR2(20)(void); +void SAVE_FPR2(21)(void); +void SAVE_FPR2(22)(void); +void SAVE_FPR2(23)(void); +void SAVE_FPR2(24)(void); +void SAVE_FPR2(25)(void); +void SAVE_FPR2(26)(void); +void SAVE_FPR2(27)(void); +void SAVE_FPR2(28)(void); +void SAVE_FPR2(29)(void); +void SAVE_FPR2(30)(void); +void SAVE_FPR2(31)(void); +void RESTORE_FPR(14)(void); +void RESTORE_FPR(15)(void); +void RESTORE_FPR(16)(void); +void RESTORE_FPR(17)(void); +void RESTORE_FPR(18)(void); +void RESTORE_FPR(19)(void); +void RESTORE_FPR(20)(void); +void RESTORE_FPR(21)(void); +void RESTORE_FPR(22)(void); +void RESTORE_FPR(23)(void); +void RESTORE_FPR(24)(void); +void RESTORE_FPR(25)(void); +void RESTORE_FPR(26)(void); +void RESTORE_FPR(27)(void); +void RESTORE_FPR(28)(void); +void RESTORE_FPR(29)(void); +void RESTORE_FPR(30)(void); +void RESTORE_FPR(31)(void); +void RESTORE_FPR2(14)(void); +void RESTORE_FPR2(15)(void); +void RESTORE_FPR2(16)(void); +void RESTORE_FPR2(17)(void); +void RESTORE_FPR2(18)(void); +void RESTORE_FPR2(19)(void); +void RESTORE_FPR2(20)(void); +void RESTORE_FPR2(21)(void); +void RESTORE_FPR2(22)(void); +void RESTORE_FPR2(23)(void); +void RESTORE_FPR2(24)(void); +void RESTORE_FPR2(25)(void); +void RESTORE_FPR2(26)(void); +void RESTORE_FPR2(27)(void); +void RESTORE_FPR2(28)(void); +void RESTORE_FPR2(29)(void); +void RESTORE_FPR2(30)(void); +void RESTORE_FPR2(31)(void); +void SAVE_GPR(14)(void); +void SAVE_GPR(15)(void); +void SAVE_GPR(16)(void); +void SAVE_GPR(17)(void); +void SAVE_GPR(18)(void); +void SAVE_GPR(19)(void); +void SAVE_GPR(20)(void); +void SAVE_GPR(21)(void); +void SAVE_GPR(22)(void); +void SAVE_GPR(23)(void); +void SAVE_GPR(24)(void); +void SAVE_GPR(25)(void); +void SAVE_GPR(26)(void); +void SAVE_GPR(27)(void); +void SAVE_GPR(28)(void); +void SAVE_GPR(29)(void); +void SAVE_GPR(30)(void); +void SAVE_GPR(31)(void); +void RESTORE_GPR(14)(void); +void RESTORE_GPR(15)(void); +void RESTORE_GPR(16)(void); +void RESTORE_GPR(17)(void); +void RESTORE_GPR(18)(void); +void RESTORE_GPR(19)(void); +void RESTORE_GPR(20)(void); +void RESTORE_GPR(21)(void); +void RESTORE_GPR(22)(void); +void RESTORE_GPR(23)(void); +void RESTORE_GPR(24)(void); +void RESTORE_GPR(25)(void); +void RESTORE_GPR(26)(void); +void RESTORE_GPR(27)(void); +void RESTORE_GPR(28)(void); +void RESTORE_GPR(29)(void); +void RESTORE_GPR(30)(void); +void RESTORE_GPR(31)(void); + +static const unsigned long __constants[] = { + 0x00000000, 0x00000000, + 0x41F00000, 0x00000000, + 0x41E00000, 0x00000000, +}; + +asm unsigned long __cvt_fp2unsigned(register double d) +{ + nofralloc + stwu r1,-16(r1) + lis r4, __constants@h + addi r4, r4, __constants@l + li r3,0 + lfd fp0,0(r4) + lfd fp3,8(r4) + lfd fp4,16(r4) + fcmpu cr0,fp1,fp0 + fcmpu cr6,fp1,fp3 + blt cr0, @exit + addi r3,r3,-1 + bge cr6,@exit + fcmpu cr7,fp1,fp4 + fmr fp2,fp1 + blt cr7,@1 + fsub fp2,fp1,fp4 +@1 fctiwz fp2,fp2 + stfd fp2,8(r1) + lwz r3,12(r1) + blt cr7,@exit + addis r3,r3,-0x8000 +@exit: + addi r1,r1,16 + blr +} + +static asm void __save_fpr(void) +{ + nofralloc + ENTRY_SAVE_FPR(14) + ENTRY_SAVE_FPR2(14) + stfd fp14,-144(save_restore_reg) + ENTRY_SAVE_FPR(15) + ENTRY_SAVE_FPR2(15) + stfd fp15,-136(save_restore_reg) + ENTRY_SAVE_FPR(16) + ENTRY_SAVE_FPR2(16) + stfd fp16,-128(save_restore_reg) + ENTRY_SAVE_FPR(17) + ENTRY_SAVE_FPR2(17) + stfd fp17,-120(save_restore_reg) + ENTRY_SAVE_FPR(18) + ENTRY_SAVE_FPR2(18) + stfd fp18,-112(save_restore_reg) + ENTRY_SAVE_FPR(19) + ENTRY_SAVE_FPR2(19) + stfd fp19,-104(save_restore_reg) + ENTRY_SAVE_FPR(20) + ENTRY_SAVE_FPR2(20) + stfd fp20,-96(save_restore_reg) + ENTRY_SAVE_FPR(21) + ENTRY_SAVE_FPR2(21) + stfd fp21,-88(save_restore_reg) + ENTRY_SAVE_FPR(22) + ENTRY_SAVE_FPR2(22) + stfd fp22,-80(save_restore_reg) + ENTRY_SAVE_FPR(23) + ENTRY_SAVE_FPR2(23) + stfd fp23,-72(save_restore_reg) + ENTRY_SAVE_FPR(24) + ENTRY_SAVE_FPR2(24) + stfd fp24,-64(save_restore_reg) + ENTRY_SAVE_FPR(25) + ENTRY_SAVE_FPR2(25) + stfd fp25,-56(save_restore_reg) + ENTRY_SAVE_FPR(26) + ENTRY_SAVE_FPR2(26) + stfd fp26,-48(save_restore_reg) + ENTRY_SAVE_FPR(27) + ENTRY_SAVE_FPR2(27) + stfd fp27,-40(save_restore_reg) + ENTRY_SAVE_FPR(28) + ENTRY_SAVE_FPR2(28) + stfd fp28,-32(save_restore_reg) + ENTRY_SAVE_FPR(29) + ENTRY_SAVE_FPR2(29) + stfd fp29,-24(save_restore_reg) + ENTRY_SAVE_FPR(30) + ENTRY_SAVE_FPR2(30) + stfd fp30,-16(save_restore_reg) + ENTRY_SAVE_FPR(31) + ENTRY_SAVE_FPR2(31) + stfd fp31,-8(save_restore_reg) + blr +} + +static asm void __restore_fpr(void) +{ + nofralloc + ENTRY_RESTORE_FPR(14) + ENTRY_RESTORE_FPR2(14) + lfd fp14,-144(save_restore_reg) + ENTRY_RESTORE_FPR(15) + ENTRY_RESTORE_FPR2(15) + lfd fp15,-136(save_restore_reg) + ENTRY_RESTORE_FPR(16) + ENTRY_RESTORE_FPR2(16) + lfd fp16,-128(save_restore_reg) + ENTRY_RESTORE_FPR(17) + ENTRY_RESTORE_FPR2(17) + lfd fp17,-120(save_restore_reg) + ENTRY_RESTORE_FPR(18) + ENTRY_RESTORE_FPR2(18) + lfd fp18,-112(save_restore_reg) + ENTRY_RESTORE_FPR(19) + ENTRY_RESTORE_FPR2(19) + lfd fp19,-104(save_restore_reg) + ENTRY_RESTORE_FPR(20) + ENTRY_RESTORE_FPR2(20) + lfd fp20,-96(save_restore_reg) + ENTRY_RESTORE_FPR(21) + ENTRY_RESTORE_FPR2(21) + lfd fp21,-88(save_restore_reg) + ENTRY_RESTORE_FPR(22) + ENTRY_RESTORE_FPR2(22) + lfd fp22,-80(save_restore_reg) + ENTRY_RESTORE_FPR(23) + ENTRY_RESTORE_FPR2(23) + lfd fp23,-72(save_restore_reg) + ENTRY_RESTORE_FPR(24) + ENTRY_RESTORE_FPR2(24) + lfd fp24,-64(save_restore_reg) + ENTRY_RESTORE_FPR(25) + ENTRY_RESTORE_FPR2(25) + lfd fp25,-56(save_restore_reg) + ENTRY_RESTORE_FPR(26) + ENTRY_RESTORE_FPR2(26) + lfd fp26,-48(save_restore_reg) + ENTRY_RESTORE_FPR(27) + ENTRY_RESTORE_FPR2(27) + lfd fp27,-40(save_restore_reg) + ENTRY_RESTORE_FPR(28) + ENTRY_RESTORE_FPR2(28) + lfd fp28,-32(save_restore_reg) + ENTRY_RESTORE_FPR(29) + ENTRY_RESTORE_FPR2(29) + lfd fp29,-24(save_restore_reg) + ENTRY_RESTORE_FPR(30) + ENTRY_RESTORE_FPR2(30) + lfd fp30,-16(save_restore_reg) + ENTRY_RESTORE_FPR(31) + ENTRY_RESTORE_FPR2(31) + lfd fp31,-8(save_restore_reg) + blr +} + +static asm void __save_gpr(void) +{ + nofralloc + ENTRY_SAVE_GPR(14) + stw r14,-72(save_restore_reg) + ENTRY_SAVE_GPR(15) + stw r15,-68(save_restore_reg) + ENTRY_SAVE_GPR(16) + stw r16,-64(save_restore_reg) + ENTRY_SAVE_GPR(17) + stw r17,-60(save_restore_reg) + ENTRY_SAVE_GPR(18) + stw r18,-56(save_restore_reg) + ENTRY_SAVE_GPR(19) + stw r19,-52(save_restore_reg) + ENTRY_SAVE_GPR(20) + stw r20,-48(save_restore_reg) + ENTRY_SAVE_GPR(21) + stw r21,-44(save_restore_reg) + ENTRY_SAVE_GPR(22) + stw r22,-40(save_restore_reg) + ENTRY_SAVE_GPR(23) + stw r23,-36(save_restore_reg) + ENTRY_SAVE_GPR(24) + stw r24,-32(save_restore_reg) + ENTRY_SAVE_GPR(25) + stw r25,-28(save_restore_reg) + ENTRY_SAVE_GPR(26) + stw r26,-24(save_restore_reg) + ENTRY_SAVE_GPR(27) + stw r27,-20(save_restore_reg) + ENTRY_SAVE_GPR(28) + stw r28,-16(save_restore_reg) + ENTRY_SAVE_GPR(29) + stw r29,-12(save_restore_reg) + ENTRY_SAVE_GPR(30) + stw r30,-8(save_restore_reg) + ENTRY_SAVE_GPR(31) + stw r31,-4(save_restore_reg) + blr +} + +static asm void __restore_gpr(void) +{ + nofralloc + ENTRY_RESTORE_GPR(14) + lwz r14,-72(save_restore_reg) + ENTRY_RESTORE_GPR(15) + lwz r15,-68(save_restore_reg) + ENTRY_RESTORE_GPR(16) + lwz r16,-64(save_restore_reg) + ENTRY_RESTORE_GPR(17) + lwz r17,-60(save_restore_reg) + ENTRY_RESTORE_GPR(18) + lwz r18,-56(save_restore_reg) + ENTRY_RESTORE_GPR(19) + lwz r19,-52(save_restore_reg) + ENTRY_RESTORE_GPR(20) + lwz r20,-48(save_restore_reg) + ENTRY_RESTORE_GPR(21) + lwz r21,-44(save_restore_reg) + ENTRY_RESTORE_GPR(22) + lwz r22,-40(save_restore_reg) + ENTRY_RESTORE_GPR(23) + lwz r23,-36(save_restore_reg) + ENTRY_RESTORE_GPR(24) + lwz r24,-32(save_restore_reg) + ENTRY_RESTORE_GPR(25) + lwz r25,-28(save_restore_reg) + ENTRY_RESTORE_GPR(26) + lwz r26,-24(save_restore_reg) + ENTRY_RESTORE_GPR(27) + lwz r27,-20(save_restore_reg) + ENTRY_RESTORE_GPR(28) + lwz r28,-16(save_restore_reg) + ENTRY_RESTORE_GPR(29) + lwz r29,-12(save_restore_reg) + ENTRY_RESTORE_GPR(30) + lwz r30,-8(save_restore_reg) + ENTRY_RESTORE_GPR(31) + lwz r31,-4(save_restore_reg) + blr +} + +asm void __div2u(void) +{ + nofralloc + cmpwi cr0,r3,0 + cntlzw r0,r3 + cntlzw r9,r4 + bne cr0,lab1 + addi r0,r9,32 + lab1: + cmpwi cr0,r5,0 + cntlzw r9,r5 + cntlzw r10,r6 + bne cr0,lab2 + addi r9,r10,32 + lab2: + cmpw cr0,r0,r9 + subfic r10,r0,64 + bgt cr0,lab9 + addi r9,r9,1 + subfic r9,r9,64 + add r0,r0,r9 + subf r9,r9,r10 + mtctr r9 + cmpwi cr0,r9,32 + addi r7,r9,-32 + blt cr0,lab3 + srw r8,r3,r7 + li r7,0 + b lab4 + lab3: + srw r8,r4,r9 + subfic r7,r9,32 + slw r7,r3,r7 + or r8,r8,r7 + srw r7,r3,r9 + lab4: + cmpwi cr0,r0,32 + addic r9,r0,-32 + blt cr0,lab5 + slw r3,r4,r9 + li r4,0 + b lab6 + lab5: + slw r3,r3,r0 + subfic r9,r0,32 + srw r9,r4,r9 + or r3,r3,r9 + slw r4,r4,r0 + lab6: + li r10,-1 + addic r7,r7,0 + lab7: + adde r4,r4,r4 + adde r3,r3,r3 + adde r8,r8,r8 + adde r7,r7,r7 + subfc r0,r6,r8 + subfe. r9,r5,r7 + blt cr0,lab8 + mr r8,r0 + mr r7,r9 + addic r0,r10,1 + lab8: + bdnz lab7 + adde r4,r4,r4 + adde r3,r3,r3 + blr + lab9: + li r4,0 + li r3,0 + blr +} + +#pragma push +#pragma optimization_level 0 +#pragma optimizewithasm off +asm void __div2i(void) +{ + nofralloc + stwu r1,-16(r1) + rlwinm. r9,r3,0,0,0 + beq cr0,positive1 + subfic r4,r4,0 + subfze r3,r3 +positive1: + stw r9,8(r1) + rlwinm. r10,r5,0,0,0 + beq cr0,positive2 + subfic r6,r6,0 + subfze r5,r5 +positive2: + stw r10,12(r1) + cmpwi cr0,r3,0 + cntlzw r0,r3 + cntlzw r9,r4 + bne cr0,lab1 + addi r0,r9,32 + lab1: + cmpwi cr0,r5,0 + cntlzw r9,r5 + cntlzw r10,r6 + bne cr0,lab2 + addi r9,r10,32 + lab2: + cmpw cr0,r0,r9 + subfic r10,r0,64 + bgt cr0,lab9 + addi r9,r9,1 + subfic r9,r9,64 + add r0,r0,r9 + subf r9,r9,r10 + mtctr r9 + cmpwi cr0,r9,32 + addi r7,r9,-32 + blt cr0,lab3 + srw r8,r3,r7 + li r7,0 + b lab4 + lab3: + srw r8,r4,r9 + subfic r7,r9,32 + slw r7,r3,r7 + or r8,r8,r7 + srw r7,r3,r9 + lab4: + cmpwi cr0,r0,32 + addic r9,r0,-32 + blt cr0,lab5 + slw r3,r4,r9 + li r4,0 + b lab6 + lab5: + slw r3,r3,r0 + subfic r9,r0,32 + srw r9,r4,r9 + or r3,r3,r9 + slw r4,r4,r0 + lab6: + li r10,-1 + addic r7,r7,0 + lab7: + adde r4,r4,r4 + adde r3,r3,r3 + adde r8,r8,r8 + adde r7,r7,r7 + subfc r0,r6,r8 + subfe. r9,r5,r7 + blt cr0,lab8 + mr r8,r0 + mr r7,r9 + addic r0,r10,1 + lab8: + bdnz lab7 + adde r4,r4,r4 + adde r3,r3,r3 + lwz r9,8(r1) + lwz r10,12(r1) + xor. r7,r9,r10 + beq cr0,no_adjust + cmpwi cr0,r9,0 + subfic r4,r4,0 + subfze r3,r3 + + no_adjust: + b func_end + + lab9: + li r4,0 + li r3,0 + func_end: + addi r1,r1,16 + blr +} +#pragma pop + +#pragma push +#pragma optimization_level 0 +#pragma optimizewithasm off +asm void __mod2u(void) +{ + nofralloc + cmpwi cr0,r3,0 + cntlzw r0,r3 + cntlzw r9,r4 + bne cr0,lab1 + addi r0,r9,32 + lab1: + cmpwi cr0,r5,0 + cntlzw r9,r5 + cntlzw r10,r6 + bne cr0,lab2 + addi r9,r10,32 + lab2: + cmpw cr0,r0,r9 + subfic r10,r0,64 + bgt cr0,lab9 + addi r9,r9,1 + subfic r9,r9,64 + add r0,r0,r9 + subf r9,r9,r10 + mtctr r9 + cmpwi cr0,r9,32 + addi r7,r9,-32 + blt cr0,lab3 + srw r8,r3,r7 + li r7,0 + b lab4 + lab3: + srw r8,r4,r9 + subfic r7,r9,32 + slw r7,r3,r7 + or r8,r8,r7 + srw r7,r3,r9 + lab4: + cmpwi cr0,r0,32 + addic r9,r0,-32 + blt cr0,lab5 + slw r3,r4,r9 + li r4,0 + b lab6 + lab5: + slw r3,r3,r0 + subfic r9,r0,32 + srw r9,r4,r9 + or r3,r3,r9 + slw r4,r4,r0 + lab6: + li r10,-1 + addic r7,r7,0 + lab7: + adde r4,r4,r4 + adde r3,r3,r3 + adde r8,r8,r8 + adde r7,r7,r7 + subfc r0,r6,r8 + subfe. r9,r5,r7 + blt cr0,lab8 + mr r8,r0 + mr r7,r9 + addic r0,r10,1 + lab8: + bdnz lab7 + mr r4,r8 + mr r3,r7 + blr + lab9: + blr +} +#pragma pop + +#pragma push +#pragma optimization_level 0 +#pragma optimizewithasm off +asm void __mod2i(void) +{ + nofralloc + + cmpwi cr7,r3,0 + bge cr7,positive1 + subfic r4,r4,0 + subfze r3,r3 +positive1: + cmpwi cr0,r5,0 + bge cr0,positive2 + subfic r6,r6,0 + subfze r5,r5 +positive2: + cmpwi cr0,r3,0 + cntlzw r0,r3 + cntlzw r9,r4 + bne cr0,lab1 + addi r0,r9,32 + lab1: + cmpwi cr0,r5,0 + cntlzw r9,r5 + cntlzw r10,r6 + bne cr0,lab2 + addi r9,r10,32 + lab2: + cmpw cr0,r0,r9 + subfic r10,r0,64 + bgt cr0,lab9 + addi r9,r9,1 + subfic r9,r9,64 + add r0,r0,r9 + subf r9,r9,r10 + mtctr r9 + cmpwi cr0,r9,32 + addi r7,r9,-32 + blt cr0,lab3 + srw r8,r3,r7 + li r7,0 + b lab4 + lab3: + srw r8,r4,r9 + subfic r7,r9,32 + slw r7,r3,r7 + or r8,r8,r7 + srw r7,r3,r9 + lab4: + cmpwi cr0,r0,32 + addic r9,r0,-32 + blt cr0,lab5 + slw r3,r4,r9 + li r4,0 + b lab6 + lab5: + slw r3,r3,r0 + subfic r9,r0,32 + srw r9,r4,r9 + or r3,r3,r9 + slw r4,r4,r0 + lab6: + li r10,-1 + addic r7,r7,0 + lab7: + adde r4,r4,r4 + adde r3,r3,r3 + adde r8,r8,r8 + adde r7,r7,r7 + subfc r0,r6,r8 + subfe. r9,r5,r7 + blt cr0,lab8 + mr r8,r0 + mr r7,r9 + addic r0,r10,1 + lab8: + bdnz lab7 + mr r4,r8 + mr r3,r7 + lab9: + bge cr7,no_adjust + subfic r4,r4,0 + subfze r3,r3 + no_adjust: + blr +} +#pragma pop + +asm void __shl2i(void) +{ + nofralloc + subfic r8,r5,32 + subic r9,r5,32 + slw r3,r3,r5 + srw r10,r4,r8 + or r3,r3,r10 + slw r10,r4,r9 + or r3,r3,r10 + slw r4,r4,r5 + blr +} + +asm void __shr2u(void) +{ + nofralloc + subfic r8,r5,32 + subic r9,r5,32 + srw r4,r4,r5 + slw r10,r3,r8 + or r4,r4,r10 + srw r10,r3,r9 + or r4,r4,r10 + srw r3,r3,r5 + blr +} + +asm void __cvt_dbl_usll(void) +{ + nofralloc + stwu r1,-16(r1) + stfd f1,8(r1) + lwz r3,8(r1) + lwz r4,12(r1) + rlwinm r5,r3,12,21,31 + cmpli cr0,0,r5,1023 + bge cr0,not_fraction + li r3,0 + li r4,0 + b func_end +not_fraction: + mr r6,r3 + rlwinm r3,r3,0,12,31 + oris r3,r3,0x0010 + addi r5,r5,-1075 + cmpwi cr0,r5,0 + bge cr0,left + neg r5,r5 + subfic r8,r5,32 + subic r9,r5,32 + srw r4,r4,r5 + slw r10,r3,r8 + or r4,r4,r10 + srw r10,r3,r9 + or r4,r4,r10 + srw r3,r3,r5 + b around +left: + cmpwi cr0,r5,10 + ble+ no_overflow + rlwinm. r6,r6,0,0,0 + beq cr0,max_positive + lis r3,0x8000 + li r4,0 + b func_end +max_positive: + lis r3,0x7FFF + ori r3,r3,0xFFFF + li r4,-1 + b func_end +no_overflow: + subfic r8,r5,32 + subic r9,r5,32 + slw r3,r3,r5 + srw r10,r4,r8 + or r3,r3,r10 + slw r10,r4,r9 + or r3,r3,r10 + slw r4,r4,r5 +around: + rlwinm. r6,r6,0,0,0 + beq cr0,positive + subfic r4,r4,0 + subfze r3,r3 +positive: +func_end: + addi r1,r1,16 + blr +} + +void __cvt_dbl_ull(void) { + nofralloc + stwu r1, -0x10(r1) + stfd f1, 8(r1) + lwz r3, 8(r1) + lwz r4, 0xC(r1) + extrwi r5, r3, 11, 1 + cmplwi r5, 0x3FF + bge loc_80518FB4 + +loc_80518FA8: + li r3, 0 + li r4, 0 + b end + +loc_80518FB4: + clrrwi. r6, r3, 31 + bne loc_80518FA8 + clrlwi r3, r3, 12 + oris r3, r3, 0x10 + addi r5, r5, -0x433 + cmpwi r5, 0 + bge loc_80518FF8 + neg r5, r5 + subfic r8, r5, 0x20 + addic r9, r5, -0x20 + srw r4, r4, r5 + slw r10, r3, r8 + or r4, r4, r10 + srw r10, r3, r9 + or r4, r4, r10 + srw r3, r3, r5 + b end + +loc_80518FF8: + cmpwi r5, 0xB + ble+ loc_8051900C + li r3, -1 + li r4, -1 + b end + +loc_8051900C: + subfic r8, r5, 0x20 + addic r9, r5, -0x20 + slw r3, r3, r5 + srw r10, r4, r8 + or r3, r3, r10 + slw r10, r4, r9 + or r3, r3, r10 + slw r4, r4, r5 + +end: + addi r1, r1, 0x10 + blr +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/tools/project.py b/tools/project.py index 1de844d3..75d89416 100644 --- a/tools/project.py +++ b/tools/project.py @@ -47,6 +47,7 @@ def __init__(self, completed: bool, name: str, **options: Any) -> None: "lib": None, "mw_version": None, "progress_category": None, + "scratch_preset_id": None, "shift_jis": None, "source": name, "src_dir": None, @@ -78,6 +79,7 @@ def set_default(key: str, value: Any) -> None: set_default("asm_dir", config.asm_dir) set_default("host", False) set_default("mw_version", config.linker_version) + set_default("scratch_preset_id", config.scratch_preset_id) set_default("shift_jis", config.shift_jis) set_default("src_dir", config.src_dir) @@ -173,6 +175,8 @@ def __init__(self) -> None: True # Generate compile_commands.json for clangd ) + self.scratch_preset_id: Optional[int] = None # Default decomp.me preset ID for scratches + # Progress output, progress.json and report.json config self.progress = True # Enable progress output self.progress_all: bool = True # Include combined "all" category @@ -1372,6 +1376,7 @@ def keep_flag(flag): "platform": "gc_wii", "compiler": compiler_version, "c_flags": cflags_str, + "preset_id": obj.options["scratch_preset_id"], } if src_exists: unit_config["scratch"].update(