From f2eabdb6257c09cf2890dac5e9737912728542af Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Thu, 2 Feb 2023 17:29:19 -0400 Subject: global: Add rest of Dolphin SDK proper, add MSL, and MetroTRK Finally, it links properly. --- src/Runtime/NMWException.cpp | 49 ++ src/Runtime/NMWException.h | 16 - src/Runtime/__mem.c | 85 ++++ src/Runtime/__va_arg.c | 57 +++ src/Runtime/abort_exit.c | 17 - src/Runtime/global_destructor_chain.c | 36 +- src/Runtime/ptmf.c | 45 ++ src/Runtime/runtime.c | 842 ++++++++++++++++++++++++++++++++++ 8 files changed, 1098 insertions(+), 49 deletions(-) create mode 100644 src/Runtime/NMWException.cpp delete mode 100644 src/Runtime/NMWException.h create mode 100644 src/Runtime/__mem.c create mode 100644 src/Runtime/__va_arg.c delete mode 100644 src/Runtime/abort_exit.c create mode 100644 src/Runtime/ptmf.c create mode 100644 src/Runtime/runtime.c (limited to 'src/Runtime') diff --git a/src/Runtime/NMWException.cpp b/src/Runtime/NMWException.cpp new file mode 100644 index 0000000..1ccbad1 --- /dev/null +++ b/src/Runtime/NMWException.cpp @@ -0,0 +1,49 @@ +#include +#pragma exceptions on + +class __partial_array_destructor { +private: + void* p; + size_t size; + size_t n; + void* dtor; + +public: + size_t i; + + __partial_array_destructor(void* array, size_t elementsize, size_t nelements, void* destructor) { + p = array; + size = elementsize; + n = nelements; + dtor = destructor; + i = n; + } + + ~__partial_array_destructor() { + char* ptr; + + if (i < n && dtor) { + for (ptr = (char*)p + size * i; i > 0; i--) { + ptr -= size; + DTORCALL_COMPLETE(dtor, ptr); + } + } + } +}; + +extern "C" void __construct_array(void* ptr, void* ctor, void* dtor, size_t size, size_t n) { + __partial_array_destructor pad(ptr, size, n, dtor); + char* p; + + for (pad.i = 0, p = (char*)ptr; pad.i < n; pad.i++, p += size) + CTORCALL_COMPLETE(ctor, p); +} + +extern "C" void __destroy_arr(void* block, void* dtor, size_t size, size_t n) { + char* p; + + for (p = (char*)block + size * n; n > 0; n--) { + p -= size; + DTORCALL_COMPLETE(dtor, p); + } +} diff --git a/src/Runtime/NMWException.h b/src/Runtime/NMWException.h deleted file mode 100644 index 49b623e..0000000 --- a/src/Runtime/NMWException.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef NMWEXCEPTION_H -#define NMWEXCEPTION_H - -typedef void (dtor_func)(void *object, int free_object); -typedef struct destructor_chain dtor_chain; - -struct destructor_chain { - dtor_chain *next; - dtor_func *destructor; - void *object; -}; - -void *__register_global_object(void *object, dtor_func *destructor, dtor_chain *regmem); -void __destroy_global_chain(); - -#endif diff --git a/src/Runtime/__mem.c b/src/Runtime/__mem.c new file mode 100644 index 0000000..a5ef6c1 --- /dev/null +++ b/src/Runtime/__mem.c @@ -0,0 +1,85 @@ +#include "string.h" + +void* memcpy(void* dst, const void* src, size_t n) { + const char* p; + char* q; + int rev = ((unsigned long)src < (unsigned long)dst); + + if (!rev) { + + for (p = (const char*)src - 1, q = (char*)dst - 1, n++; --n;) + *++q = *++p; + + } else { + for (p = (const char*)src + n, q = (char*)dst + n, n++; --n;) + *--q = *--p; + } + return (dst); +} + +#define cps ((unsigned char*)src) +#define cpd ((unsigned char*)dst) +#define lps ((unsigned long*)src) +#define lpd ((unsigned long*)dst) +#define deref_auto_inc(p) *++(p) + +void __fill_mem(void* dst, int val, size_t n) { + unsigned long v = (unsigned char)val; + unsigned long i; + + cpd = ((unsigned char*)dst) - 1; + + if (n >= 32) { + i = (~(unsigned long)dst) & 3; + + if (i) { + n -= i; + + do + deref_auto_inc(cpd) = v; + while (--i); + } + + if (v) + v |= v << 24 | v << 16 | v << 8; + + lpd = ((unsigned long*)(cpd + 1)) - 1; + + i = n >> 5; + + if (i) + do { + deref_auto_inc(lpd) = v; + deref_auto_inc(lpd) = v; + deref_auto_inc(lpd) = v; + deref_auto_inc(lpd) = v; + deref_auto_inc(lpd) = v; + deref_auto_inc(lpd) = v; + deref_auto_inc(lpd) = v; + deref_auto_inc(lpd) = v; + } while (--i); + + i = (n & 31) >> 2; + + if (i) + do + deref_auto_inc(lpd) = v; + while (--i); + + cpd = ((unsigned char*)(lpd + 1)) - 1; + + n &= 3; + } + + if (n) + do + deref_auto_inc(cpd) = v; + while (--n); + + return; +} + +void* memset(void* str, int c, size_t n) { + __fill_mem(str, c, n); + return str; +} diff --git a/src/Runtime/__va_arg.c b/src/Runtime/__va_arg.c new file mode 100644 index 0000000..fd0e182 --- /dev/null +++ b/src/Runtime/__va_arg.c @@ -0,0 +1,57 @@ +typedef struct { + char gpr; + char fpr; + char reserved[2]; + char* input_arg_area; + char* reg_save_area; +} va_list[1]; + +typedef enum { + ARGPOINTER, + WORD, + DOUBLEWORD, + REAL, +} _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* curGprPtr = &(ap->gpr); + int curGpr = ap->gpr; + int max = 8; + int size = 4; + int inc = 1; + int even = 0; + int fprOffset = 0; + int regSize = 4; + + if (type == 3) { + curGprPtr = &(ap->fpr); + curGpr = ap->fpr; + size = 8; + fprOffset = 8 * 4; + regSize = 8; + } + if (type == 2) { + size = 8; + max = max - 1; + if (curGpr & 1) + even = 1; + inc = 2; + } + if (curGpr < max) { + curGpr += even; + addr = ap->reg_save_area + fprOffset + (curGpr * regSize); + *curGprPtr = curGpr + inc; + } else { + *curGprPtr = 8; + addr = ap->input_arg_area; + addr = (char*)ALIGN(addr, size); + ap->input_arg_area = addr + size; + } + if (type == ARGPOINTER) + addr = *((char**)addr); + + return addr; +} diff --git a/src/Runtime/abort_exit.c b/src/Runtime/abort_exit.c deleted file mode 100644 index 43b1a0c..0000000 --- a/src/Runtime/abort_exit.c +++ /dev/null @@ -1,17 +0,0 @@ -void __destroy_global_chain(); - -extern void (*_dtors[])(void); - -int __aborting; - - -void exit(int state) { - void (**dtor)(void); - if (!__aborting) { - dtor = _dtors; - while (*dtor != 0) { - (*dtor)(); - dtor++; - } - } -} diff --git a/src/Runtime/global_destructor_chain.c b/src/Runtime/global_destructor_chain.c index 1f3790d..7c24b76 100644 --- a/src/Runtime/global_destructor_chain.c +++ b/src/Runtime/global_destructor_chain.c @@ -1,22 +1,26 @@ #include "NMWException.h" -dtor_chain *__global_destructor_chain; - -extern void *__register_global_object(void *object, dtor_func *destructor, dtor_chain *regmem) { - regmem->next = __global_destructor_chain; - regmem->destructor = destructor; - regmem->object = object; - __global_destructor_chain = regmem; - return object; + + +DestructorChain* __global_destructor_chain; + +extern void* __register_global_object(void* object, void* destructor, void* regmem) { + ((DestructorChain*)regmem)->next = __global_destructor_chain; + ((DestructorChain*)regmem)->destructor = destructor; + ((DestructorChain*)regmem)->object = object; + __global_destructor_chain = (DestructorChain*)regmem; + + return object; } -void __destroy_global_chain() { - dtor_chain *iter = __global_destructor_chain; - while (__global_destructor_chain != 0) { - iter = __global_destructor_chain; - __global_destructor_chain = __global_destructor_chain->next; - iter->destructor(iter->object, -1); - } +void __destroy_global_chain(void) { + DestructorChain* iter; + + while ((iter=__global_destructor_chain) != 0) { + __global_destructor_chain = iter->next; + DTORCALL_COMPLETE(iter->destructor, iter->object); + } } -__declspec(section ".dtors") static void* const __destroy_global_chain_reference = __destroy_global_chain; +__declspec(section + ".dtors") static void* const __destroy_global_chain_reference = __destroy_global_chain; diff --git a/src/Runtime/ptmf.c b/src/Runtime/ptmf.c new file mode 100644 index 0000000..b9e8a90 --- /dev/null +++ b/src/Runtime/ptmf.c @@ -0,0 +1,45 @@ + +typedef struct PTMF { + long this_delta; // delta to this pointer + long vtbl_offset; // offset in vtable (-1: not a virtual function) + union { + void* func_addr; //nonvirtual function address + long ventry_offset; // of virtual function entry in vtable + } func_data; +} PTMF; + +const PTMF __ptmf_null = {0, 0, 0}; + +/* clang-format off */ +asm void __ptmf_test(register PTMF* ptmf) { + nofralloc + + lwz r5, PTMF.this_delta(ptmf) + lwz r6, PTMF.vtbl_offset(ptmf) + lwz r7, PTMF.func_data(ptmf) + 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 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 r11, 0 + blt @1 + lwzx r12, r3, r12 + lwzx r12, r12, r11 +@1 + mtctr r12 + bctr +} +/* clang-format - on*/ diff --git a/src/Runtime/runtime.c b/src/Runtime/runtime.c new file mode 100644 index 0000000..16fd6ed --- /dev/null +++ b/src/Runtime/runtime.c @@ -0,0 +1,842 @@ +/* clang-format off */ +#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) + + +#ifdef __cplusplus +extern "C" { +#endif + +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 long __constants[] = { + 0x0000000000000000, // 0.0 + 0x41F0000000000000, // 2**32 + 0x41E0000000000000, // 2**31 +}; + + +asm unsigned long __cvt_fp2unsigned(register double d) { + nofralloc + stwu r1, -0x10(r1) + lis r4, __constants@h + ori r4, r4, __constants@l + li r3, 0 + lfd f0, 0(r4) + lfd f3, 8(r4) + lfd f4, 0x10(r4) + fcmpu cr0, f1, f0 + fcmpu cr6, f1, f3 + blt lbl_803899A8 + addi r3, r3, -1 + bge cr6, lbl_803899A8 + fcmpu cr7, f1, f4 + fmr f2, f1 + blt cr7, lbl_80389994 + fsub f2, f1, f4 +lbl_80389994: + fctiwz f2, f2 + stfd f2, 8(r1) + lwz r3, 0xc(r1) + blt cr7, lbl_803899A8 + addis r3, r3, 0x8000 +lbl_803899A8: + addi r1, r1, 0x10 + blr +} + + +asm void __save_fpr() { + ENTRY_SAVE_FPR(14) + ENTRY_SAVE_FPR2(14) + stfd fp14,-144 (r11) + ENTRY_SAVE_FPR(15) + ENTRY_SAVE_FPR2(15) + stfd fp15,-136 (r11) + ENTRY_SAVE_FPR(16) + ENTRY_SAVE_FPR2(16) + stfd fp16,-128 (r11) + ENTRY_SAVE_FPR(17) + ENTRY_SAVE_FPR2(17) + stfd fp17,-120 (r11) + ENTRY_SAVE_FPR(18) + ENTRY_SAVE_FPR2(18) + stfd fp18,-112 (r11) + ENTRY_SAVE_FPR(19) + ENTRY_SAVE_FPR2(19) + stfd fp19,-104 (r11) + ENTRY_SAVE_FPR(20) + ENTRY_SAVE_FPR2(20) + stfd fp20,-96 (r11) + ENTRY_SAVE_FPR(21) + ENTRY_SAVE_FPR2(21) + stfd fp21,-88 (r11) + ENTRY_SAVE_FPR(22) + ENTRY_SAVE_FPR2(22) + stfd fp22,-80(r11) + ENTRY_SAVE_FPR(23) + ENTRY_SAVE_FPR2(23) + stfd fp23,-72(r11) + ENTRY_SAVE_FPR(24) + ENTRY_SAVE_FPR2(24) + stfd fp24,-64(r11) + ENTRY_SAVE_FPR(25) + ENTRY_SAVE_FPR2(25) + stfd fp25,-56(r11) + ENTRY_SAVE_FPR(26) + ENTRY_SAVE_FPR2(26) + stfd fp26,-48(r11) + ENTRY_SAVE_FPR(27) + ENTRY_SAVE_FPR2(27) + stfd fp27,-40(r11) + ENTRY_SAVE_FPR(28) + ENTRY_SAVE_FPR2(28) + stfd fp28,-32(r11) + ENTRY_SAVE_FPR(29) + ENTRY_SAVE_FPR2(29) + stfd fp29,-24(r11) + ENTRY_SAVE_FPR(30) + ENTRY_SAVE_FPR2(30) + stfd fp30,-16(r11) + ENTRY_SAVE_FPR(31) + ENTRY_SAVE_FPR2(31) + stfd fp31,-8(r11) + blr +} + +asm void __restore_fpr(void) { + nofralloc + ENTRY_RESTORE_FPR(14) + ENTRY_RESTORE_FPR2(14) + lfd fp14,-144(r11) + ENTRY_RESTORE_FPR(15) + ENTRY_RESTORE_FPR2(15) + lfd fp15,-136(r11) + ENTRY_RESTORE_FPR(16) + ENTRY_RESTORE_FPR2(16) + lfd fp16,-128(r11) + ENTRY_RESTORE_FPR(17) + ENTRY_RESTORE_FPR2(17) + lfd fp17,-120(r11) + ENTRY_RESTORE_FPR(18) + ENTRY_RESTORE_FPR2(18) + lfd fp18,-112(r11) + ENTRY_RESTORE_FPR(19) + ENTRY_RESTORE_FPR2(19) + lfd fp19,-104(r11) + ENTRY_RESTORE_FPR(20) + ENTRY_RESTORE_FPR2(20) + lfd fp20,-96(r11) + ENTRY_RESTORE_FPR(21) + ENTRY_RESTORE_FPR2(21) + lfd fp21,-88(r11) + ENTRY_RESTORE_FPR(22) + ENTRY_RESTORE_FPR2(22) + lfd fp22,-80(r11) + ENTRY_RESTORE_FPR(23) + ENTRY_RESTORE_FPR2(23) + lfd fp23,-72(r11) + ENTRY_RESTORE_FPR(24) + ENTRY_RESTORE_FPR2(24) + lfd fp24,-64(r11) + ENTRY_RESTORE_FPR(25) + ENTRY_RESTORE_FPR2(25) + lfd fp25,-56(r11) + ENTRY_RESTORE_FPR(26) + ENTRY_RESTORE_FPR2(26) + lfd fp26,-48(r11) + ENTRY_RESTORE_FPR(27) + ENTRY_RESTORE_FPR2(27) + lfd fp27,-40(r11) + ENTRY_RESTORE_FPR(28) + ENTRY_RESTORE_FPR2(28) + lfd fp28,-32(r11) + ENTRY_RESTORE_FPR(29) + ENTRY_RESTORE_FPR2(29) + lfd fp29,-24(r11) + ENTRY_RESTORE_FPR(30) + ENTRY_RESTORE_FPR2(30) + lfd fp30,-16(r11) + ENTRY_RESTORE_FPR(31) + ENTRY_RESTORE_FPR2(31) + lfd fp31,-8(r11) + blr +} + +asm void __save_gpr(void) { + nofralloc + ENTRY_SAVE_GPR(14) + stw r14,-72(r11) + ENTRY_SAVE_GPR(15) + stw r15,-68(r11) + ENTRY_SAVE_GPR(16) + stw r16,-64(r11) + ENTRY_SAVE_GPR(17) + stw r17,-60(r11) + ENTRY_SAVE_GPR(18) + stw r18,-56(r11) + ENTRY_SAVE_GPR(19) + stw r19,-52(r11) + ENTRY_SAVE_GPR(20) + stw r20,-48(r11) + ENTRY_SAVE_GPR(21) + stw r21,-44(r11) + ENTRY_SAVE_GPR(22) + stw r22,-40(r11) + ENTRY_SAVE_GPR(23) + stw r23,-36(r11) + ENTRY_SAVE_GPR(24) + stw r24,-32(r11) + ENTRY_SAVE_GPR(25) + stw r25,-28(r11) + ENTRY_SAVE_GPR(26) + stw r26,-24(r11) + ENTRY_SAVE_GPR(27) + stw r27,-20(r11) + ENTRY_SAVE_GPR(28) + stw r28,-16(r11) + ENTRY_SAVE_GPR(29) + stw r29,-12(r11) + ENTRY_SAVE_GPR(30) + stw r30,-8(r11) + ENTRY_SAVE_GPR(31) + stw r31,-4(r11) + blr +} + +asm void __restore_gpr(void) { + nofralloc + ENTRY_RESTORE_GPR(14) + lwz r14,-72(r11) + ENTRY_RESTORE_GPR(15) + lwz r15,-68(r11) + ENTRY_RESTORE_GPR(16) + lwz r16,-64(r11) + ENTRY_RESTORE_GPR(17) + lwz r17,-60(r11) + ENTRY_RESTORE_GPR(18) + lwz r18,-56(r11) + ENTRY_RESTORE_GPR(19) + lwz r19,-52(r11) + ENTRY_RESTORE_GPR(20) + lwz r20,-48(r11) + ENTRY_RESTORE_GPR(21) + lwz r21,-44(r11) + ENTRY_RESTORE_GPR(22) + lwz r22,-40(r11) + ENTRY_RESTORE_GPR(23) + lwz r23,-36(r11) + ENTRY_RESTORE_GPR(24) + lwz r24,-32(r11) + ENTRY_RESTORE_GPR(25) + lwz r25,-28(r11) + ENTRY_RESTORE_GPR(26) + lwz r26,-24(r11) + ENTRY_RESTORE_GPR(27) + lwz r27,-20(r11) + ENTRY_RESTORE_GPR(28) + lwz r28,-16(r11) + ENTRY_RESTORE_GPR(29) + lwz r29,-12(r11) + ENTRY_RESTORE_GPR(30) + lwz r30,-8(r11) + ENTRY_RESTORE_GPR(31) + lwz r31,-4(r11) + blr +} + +asm void __div2u(void) { + nofralloc + cmpwi r3, 0 + cntlzw r0, r3 + cntlzw r9, r4 + bne lbl_80389AF4 + addi r0, r9, 0x20 +lbl_80389AF4: + cmpwi r5, 0 + cntlzw r9, r5 + cntlzw r10, r6 + bne lbl_80389B08 + addi r9, r10, 0x20 +lbl_80389B08: + cmpw r0, r9 + subfic r10, r0, 0x40 + bgt lbl_80389BC0 + addi r9, r9, 1 + subfic r9, r9, 0x40 + add r0, r0, r9 + subf r9, r9, r10 + mtctr r9 + cmpwi r9, 0x20 + addi r7, r9, -32 + blt lbl_80389B40 + srw r8, r3, r7 + li r7, 0 + b lbl_80389B54 +lbl_80389B40: + srw r8, r4, r9 + subfic r7, r9, 0x20 + slw r7, r3, r7 + or r8, r8, r7 + srw r7, r3, r9 +lbl_80389B54: + cmpwi r0, 0x20 + addic r9, r0, -32 + blt lbl_80389B6C + slw r3, r4, r9 + li r4, 0 + b lbl_80389B80 +lbl_80389B6C: + slw r3, r3, r0 + subfic r9, r0, 0x20 + srw r9, r4, r9 + or r3, r3, r9 + slw r4, r4, r0 +lbl_80389B80: + li r10, -1 + addic r7, r7, 0 +lbl_80389B88: + 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 lbl_80389BB0 + mr r8, r0 + mr r7, r9 + addic r0, r10, 1 +lbl_80389BB0: + bdnz lbl_80389B88 + adde r4, r4, r4 + adde r3, r3, r3 + blr +lbl_80389BC0: + li r4, 0 + li r3, 0 + blr +} + +asm void __div2i(void) { + nofralloc + stwu r1, -0x10(r1) + rlwinm. r9, r3, 0, 0, 0 + beq lbl_80389BE0 + subfic r4, r4, 0 + subfze r3, r3 +lbl_80389BE0: + stw r9, 8(r1) + rlwinm. r10, r5, 0, 0, 0 + beq lbl_80389BF4 + subfic r6, r6, 0 + subfze r5, r5 +lbl_80389BF4: + stw r10, 0xc(r1) + cmpwi r3, 0 + cntlzw r0, r3 + cntlzw r9, r4 + bne lbl_80389C0C + addi r0, r9, 0x20 +lbl_80389C0C: + cmpwi r5, 0 + cntlzw r9, r5 + cntlzw r10, r6 + bne lbl_80389C20 + addi r9, r10, 0x20 +lbl_80389C20: + cmpw r0, r9 + subfic r10, r0, 0x40 + bgt lbl_80389CF4 + addi r9, r9, 1 + subfic r9, r9, 0x40 + add r0, r0, r9 + subf r9, r9, r10 + mtctr r9 + cmpwi r9, 0x20 + addi r7, r9, -32 + blt lbl_80389C58 + srw r8, r3, r7 + li r7, 0 + b lbl_80389C6C +lbl_80389C58: + srw r8, r4, r9 + subfic r7, r9, 0x20 + slw r7, r3, r7 + or r8, r8, r7 + srw r7, r3, r9 +lbl_80389C6C: + cmpwi r0, 0x20 + addic r9, r0, -32 + blt lbl_80389C84 + slw r3, r4, r9 + li r4, 0 + b lbl_80389C98 +lbl_80389C84: + slw r3, r3, r0 + subfic r9, r0, 0x20 + srw r9, r4, r9 + or r3, r3, r9 + slw r4, r4, r0 +lbl_80389C98: + li r10, -1 + addic r7, r7, 0 +lbl_80389CA0: + 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 lbl_80389CC8 + mr r8, r0 + mr r7, r9 + addic r0, r10, 1 +lbl_80389CC8: + bdnz lbl_80389CA0 + adde r4, r4, r4 + adde r3, r3, r3 + lwz r9, 8(r1) + lwz r10, 0xc(r1) + xor. r7, r9, r10 + beq lbl_80389CFC + cmpwi r9, 0 + subfic r4, r4, 0 + subfze r3, r3 + b lbl_80389CFC +lbl_80389CF4: + li r4, 0 + li r3, 0 +lbl_80389CFC: + addi r1, r1, 0x10 + blr +} + +asm void __mod2u() { + nofralloc + cmpwi r3, 0 + cntlzw r0, r3 + cntlzw r9, r4 + bne lbl_80389D18 + addi r0, r9, 0x20 +lbl_80389D18: + cmpwi r5, 0 + cntlzw r9, r5 + cntlzw r10, r6 + bne lbl_80389D2C + addi r9, r10, 0x20 +lbl_80389D2C: + cmpw r0, r9 + subfic r10, r0, 0x40 + bgtlr + addi r9, r9, 1 + subfic r9, r9, 0x40 + add r0, r0, r9 + subf r9, r9, r10 + mtctr r9 + cmpwi r9, 0x20 + addi r7, r9, -32 + blt lbl_80389D64 + srw r8, r3, r7 + li r7, 0 + b lbl_80389D78 +lbl_80389D64: + srw r8, r4, r9 + subfic r7, r9, 0x20 + slw r7, r3, r7 + or r8, r8, r7 + srw r7, r3, r9 +lbl_80389D78: + cmpwi r0, 0x20 + addic r9, r0, -32 + blt lbl_80389D90 + slw r3, r4, r9 + li r4, 0 + b lbl_80389DA4 +lbl_80389D90: + slw r3, r3, r0 + subfic r9, r0, 0x20 + srw r9, r4, r9 + or r3, r3, r9 + slw r4, r4, r0 +lbl_80389DA4: + li r10, -1 + addic r7, r7, 0 +lbl_80389DAC: + 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 lbl_80389DD4 + mr r8, r0 + mr r7, r9 + addic r0, r10, 1 +lbl_80389DD4: + bdnz lbl_80389DAC + mr r4, r8 + mr r3, r7 + blr + blr +} + +asm void __mod2i(void) { + nofralloc + cmpwi cr7, r3, 0 + bge cr7, lbl_80389DF8 + subfic r4, r4, 0 + subfze r3, r3 +lbl_80389DF8: + cmpwi r5, 0 + bge lbl_80389E08 + subfic r6, r6, 0 + subfze r5, r5 +lbl_80389E08: + cmpwi r3, 0 + cntlzw r0, r3 + cntlzw r9, r4 + bne lbl_80389E1C + addi r0, r9, 0x20 +lbl_80389E1C: + cmpwi r5, 0 + cntlzw r9, r5 + cntlzw r10, r6 + bne lbl_80389E30 + addi r9, r10, 0x20 +lbl_80389E30: + cmpw r0, r9 + subfic r10, r0, 0x40 + bgt lbl_80389EE4 + addi r9, r9, 1 + subfic r9, r9, 0x40 + add r0, r0, r9 + subf r9, r9, r10 + mtctr r9 + cmpwi r9, 0x20 + addi r7, r9, -32 + blt lbl_80389E68 + srw r8, r3, r7 + li r7, 0 + b lbl_80389E7C +lbl_80389E68: + srw r8, r4, r9 + subfic r7, r9, 0x20 + slw r7, r3, r7 + or r8, r8, r7 + srw r7, r3, r9 +lbl_80389E7C: + cmpwi r0, 0x20 + addic r9, r0, -32 + blt lbl_80389E94 + slw r3, r4, r9 + li r4, 0 + b lbl_80389EA8 +lbl_80389E94: + slw r3, r3, r0 + subfic r9, r0, 0x20 + srw r9, r4, r9 + or r3, r3, r9 + slw r4, r4, r0 +lbl_80389EA8: + li r10, -1 + addic r7, r7, 0 +lbl_80389EB0: + 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 lbl_80389ED8 + mr r8, r0 + mr r7, r9 + addic r0, r10, 1 +lbl_80389ED8: + bdnz lbl_80389EB0 + mr r4, r8 + mr r3, r7 +lbl_80389EE4: + bgelr cr7 + subfic r4, r4, 0 + subfze r3, r3 + blr +} + +asm void __shl2i() { + nofralloc + subfic r8, r5, 0x20 + addic 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() { + nofralloc + subfic r8, r5, 0x20 + addic 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 __shr2i() { + nofralloc + subfic r8, r5, 0x20 + addic. r9, r5, -32 + srw r4, r4, r5 + slw r10, r3, r8 + or r4, r4, r10 + sraw r10, r3, r9 + ble lbl_80389F5C + or r4, r4, r10 +lbl_80389F5C: + sraw r3, r3, r5 + blr +} + +asm void __cvt_sll_flt(void) { + nofralloc + stwu r1, -0x10(r1) + rlwinm. r5, r3, 0, 0, 0 + beq lbl_80389F78 + subfic r4, r4, 0 + subfze r3, r3 +lbl_80389F78: + or. r7, r3, r4 + li r6, 0 + beq lbl_8038A000 + cntlzw r7, r3 + cntlzw r8, r4 + rlwinm r9, r7, 0x1a, 0, 4 + srawi r9, r9, 0x1f + and r9, r9, r8 + add r7, r7, r9 + subfic r8, r7, 0x20 + addic r9, r7, -32 + slw r3, r3, r7 + srw r10, r4, r8 + or r3, r3, r10 + slw r10, r4, r9 + or r3, r3, r10 + slw r4, r4, r7 + subf r6, r7, r6 + clrlwi r7, r4, 0x15 + cmpwi r7, 0x400 + addi r6, r6, 0x43e + blt lbl_80389FE8 + bgt lbl_80389FDC + rlwinm. r7, r4, 0, 0x14, 0x14 + beq lbl_80389FE8 +lbl_80389FDC: + addic r4, r4, 0x800 + addze r3, r3 + addze r6, r6 +lbl_80389FE8: + rotlwi r4, r4, 0x15 + rlwimi r4, r3, 0x15, 0, 0xa + rlwinm r3, r3, 0x15, 0xc, 0x1f + slwi r6, r6, 0x14 + or r3, r6, r3 + or r3, r5, r3 +lbl_8038A000: + stw r3, 8(r1) + stw r4, 0xc(r1) + lfd f1, 8(r1) + frsp f1, f1 + addi r1, r1, 0x10 + blr +} + +asm unsigned long __cvt_dbl_usll(register double d) { + nofralloc + stwu r1, -0x10(r1) + stfd f1, 8(r1) + lwz r3, 8(r1) + lwz r4, 0xc(r1) + rlwinm r5, r3, 0xc, 0x15, 0x1f + cmplwi r5, 0x3ff + bge lbl_8038A040 + li r3, 0 + li r4, 0 + b lbl_8038A0DC +lbl_8038A040: + mr r6, r3 + clrlwi r3, r3, 0xc + oris r3, r3, 0x10 + addi r5, r5, -1075 + cmpwi r5, 0 + bge lbl_8038A080 + neg r5, r5 + subfic r8, r5, 0x20 + addic 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 lbl_8038A0CC +lbl_8038A080: + cmpwi r5, 0xa + ble+ lbl_8038A0AC + rlwinm. r6, r6, 0, 0, 0 + beq lbl_8038A09C + lis r3, 0x8000 + li r4, 0 + b lbl_8038A0DC +lbl_8038A09C: + lis r3, 0x7FFFFFFF@h + ori r3, r3, 0x7FFFFFFF@l + li r4, -1 + b lbl_8038A0DC +lbl_8038A0AC: + subfic r8, r5, 0x20 + addic 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 +lbl_8038A0CC: + rlwinm. r6, r6, 0, 0, 0 + beq lbl_8038A0DC + subfic r4, r4, 0 + subfze r3, r3 +lbl_8038A0DC: + addi r1, r1, 0x10 + blr +} + +#ifdef __cplusplus +} +#endif -- cgit v1.2.3-13-gbd6f