mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-22 22:24:16 -04:00
Steal MSL runtime from sms & mkdd
This commit is contained in:
+7
-7
@@ -861,19 +861,19 @@ config.libs = [
|
||||
{
|
||||
"lib": "Runtime.PPCEABI.H",
|
||||
"mw_version": config.linker_version,
|
||||
"cflags": cflags_runtime,
|
||||
"cflags": [*cflags_runtime, "-inline auto,deferred", "-use_lmw_stmw on", "-char signed", "-fp_contract on"],
|
||||
"progress_category": "sdk",
|
||||
"src_dir": "src/static",
|
||||
"objects": [
|
||||
Object(Matching, "Runtime.PPCEABI.H/__init_cpp_exceptions.cpp"),
|
||||
Object(Matching, "Runtime.PPCEABI.H/__mem.c"),
|
||||
Object(NonMatching, "Runtime.PPCEABI.H/__va_arg.c"),
|
||||
Object(NonMatching, "Runtime.PPCEABI.H/CPlusLibPPC.cp"),
|
||||
Object(NonMatching, "Runtime.PPCEABI.H/Gecko_ExceptionPPC.cp"),
|
||||
Object(Matching, "Runtime.PPCEABI.H/__va_arg.c"),
|
||||
Object(Matching, "Runtime.PPCEABI.H/CPlusLibPPC.cp"),
|
||||
Object(Matching, "Runtime.PPCEABI.H/Gecko_ExceptionPPC.cp"),
|
||||
Object(Matching, "Runtime.PPCEABI.H/global_destructor_chain.c"),
|
||||
Object(NonMatching, "Runtime.PPCEABI.H/NMWException.cp"),
|
||||
Object(NonMatching, "Runtime.PPCEABI.H/ptmf.c"),
|
||||
Object(NonMatching, "Runtime.PPCEABI.H/runtime.c"),
|
||||
Object(Matching, "Runtime.PPCEABI.H/NMWException.cp"),
|
||||
Object(Matching, "Runtime.PPCEABI.H/ptmf.c"),
|
||||
Object(Matching, "Runtime.PPCEABI.H/runtime.c"),
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef _RUNTIME_MWCPLUSLIB_H
|
||||
#define _RUNTIME_MWCPLUSLIB_H
|
||||
|
||||
#include "stddef.h"
|
||||
|
||||
#define CTORARG_TYPE int
|
||||
#define CTORARG_PARTIAL (0)
|
||||
#define CTORARG_COMPLETE (1)
|
||||
|
||||
#define CTORCALL_COMPLETE(ctor, objptr) (((void (*)(void*, CTORARG_TYPE))ctor)(objptr, CTORARG_COMPLETE))
|
||||
|
||||
#define DTORARG_TYPE int
|
||||
|
||||
#define DTORCALL_COMPLETE(dtor, objptr) (((void (*)(void*, DTORARG_TYPE))dtor)(objptr, -1))
|
||||
#define DTORCALL_PARTIAL(dtor, objptr) (((void (*)(void*, DTORARG_TYPE))dtor)(objptr, 0))
|
||||
|
||||
typedef void* ConstructorDestructor;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void* __copy(char* to, char* from, size_t size);
|
||||
|
||||
extern void __construct_array(void* ptr, ConstructorDestructor ctor, ConstructorDestructor dtor, size_t size, size_t n);
|
||||
extern void __destroy_arr(void* block, ConstructorDestructor* dtor, size_t size, size_t n);
|
||||
extern void* __construct_new_array(void* block, ConstructorDestructor ctor, ConstructorDestructor dtor_arg, size_t size,
|
||||
size_t n);
|
||||
extern void __destroy_new_array(void* block, ConstructorDestructor dtor);
|
||||
extern void __destroy_new_array2();
|
||||
extern void __destroy_new_array3();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,41 @@
|
||||
#ifndef _NMWEXCEPTION
|
||||
#define _NMWEXCEPTION
|
||||
|
||||
typedef short vbase_ctor_arg_type;
|
||||
typedef char local_cond_type;
|
||||
|
||||
typedef struct CatchInfo {
|
||||
void* location;
|
||||
void* typeinfo;
|
||||
void* dtor;
|
||||
void* sublocation;
|
||||
long pointercopy;
|
||||
void* stacktop;
|
||||
} CatchInfo;
|
||||
|
||||
typedef struct DestructorChain {
|
||||
struct DestructorChain* next;
|
||||
void* destructor;
|
||||
void* object;
|
||||
} DestructorChain;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void* __register_global_object(void* object, void* destructor, void* registration);
|
||||
extern void __destroy_global_chain(void);
|
||||
|
||||
extern void __end__catch(CatchInfo* catchinfo);
|
||||
extern void __throw(char* throwtype, void* location, void* dtor);
|
||||
extern char __throw_catch_compare(const char* throwtype, const char* catchtype, long* offset_result);
|
||||
extern void __unexpected(CatchInfo* catchinfo);
|
||||
|
||||
extern int __register_fragment(struct __eti_init_info* info, char* TOC);
|
||||
extern void __unregister_fragment(int fragmentID);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _NMWEXCEPTION
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
#ifndef _MEM_H
|
||||
#define _MEM_H
|
||||
|
||||
#include "types.h"
|
||||
#include "stddef.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@@ -19,7 +19,7 @@ typedef __va_list va_list;
|
||||
extern void __builtin_va_info(va_list*);
|
||||
#endif
|
||||
|
||||
void* __va_arg(va_list v_list, unsigned char type);
|
||||
void* __va_arg(va_list v_list, int type);
|
||||
|
||||
#define va_start(ap, fmt) ((void)fmt, __builtin_va_info(&ap))
|
||||
#define va_arg(ap, t) (*((t*)__va_arg(ap, _var_arg_typeof(t))))
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ typedef struct __va_list_struct {
|
||||
|
||||
typedef _va_list_struct __va_list[1];
|
||||
|
||||
void* __va_arg(_va_list_struct* list, int type);
|
||||
void* __va_arg(_va_list_struct* list, long type);
|
||||
|
||||
#define __va_start(list, fmt) __builtin_va_info(&list)
|
||||
#ifdef __MWERKS__
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
extern "C" char* __copy(char* r3, char* r4, unsigned long r5) {
|
||||
if (!r3)
|
||||
return r3;
|
||||
if (!r5)
|
||||
return r3;
|
||||
char* d = (char*)r3;
|
||||
do {
|
||||
*d++ = *r4++;
|
||||
} while (--r5);
|
||||
return r3;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#include "Runtime.PPCEABI.H/NMWException.h"
|
||||
|
||||
// NOTE: there is a bug in mwcc where any pure-asm function
|
||||
// disables this optimization but doesn't reset it to be on
|
||||
// original probably had an asm function in one of the headers
|
||||
// above, but no idea which for now
|
||||
#pragma peephole off
|
||||
|
||||
typedef struct ProcessInfo {
|
||||
__eti_init_info* exception_info;
|
||||
char* TOC;
|
||||
int active;
|
||||
} ProcessInfo;
|
||||
|
||||
#define MAXFRAGMENTS 1
|
||||
static ProcessInfo fragmentinfo[MAXFRAGMENTS];
|
||||
|
||||
int __register_fragment(struct __eti_init_info* info, char* TOC)
|
||||
{
|
||||
ProcessInfo* f = fragmentinfo;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAXFRAGMENTS; i++, f++) {
|
||||
if (f->active == 0) {
|
||||
f->exception_info = info;
|
||||
f->TOC = TOC;
|
||||
f->active = 1;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void __unregister_fragment(int fragmentID)
|
||||
{
|
||||
ProcessInfo* f;
|
||||
|
||||
if (fragmentID >= 0 && fragmentID < MAXFRAGMENTS) {
|
||||
f = &fragmentinfo[fragmentID];
|
||||
f->exception_info = 0;
|
||||
f->TOC = 0;
|
||||
f->active = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#include "Runtime.PPCEABI.H/NMWException.h"
|
||||
#include "Runtime.PPCEABI.H/MWCPlusLib.h"
|
||||
|
||||
#pragma exceptions on
|
||||
|
||||
#define ARRAY_HEADER_SIZE 8
|
||||
|
||||
class __partial_array_destructor {
|
||||
private:
|
||||
void* p;
|
||||
size_t size;
|
||||
size_t n;
|
||||
ConstructorDestructor dtor;
|
||||
|
||||
public:
|
||||
size_t i;
|
||||
|
||||
__partial_array_destructor(void* array, size_t elementsize, size_t nelements, ConstructorDestructor 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 void __construct_array(void* ptr, ConstructorDestructor ctor, ConstructorDestructor 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 void __destroy_arr(void* block, ConstructorDestructor* dtor, size_t size, size_t n) {
|
||||
char* p;
|
||||
|
||||
for (p = (char*)block + size * n; n > 0; n--) {
|
||||
p -= size;
|
||||
DTORCALL_COMPLETE(dtor, p);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
static int fragmentID = -2;
|
||||
|
||||
extern char* GetR2(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -24,12 +26,10 @@ extern void __destroy_global_chain(void);
|
||||
}
|
||||
#endif
|
||||
|
||||
asm char* GetR2(void) {
|
||||
// clang-format off
|
||||
nofralloc
|
||||
mr r3, r2
|
||||
blr
|
||||
// clang-format on
|
||||
extern void __init_cpp_exceptions(void) {
|
||||
if (fragmentID == -2) {
|
||||
fragmentID = __register_fragment(&_eti_init_info, GetR2());
|
||||
}
|
||||
}
|
||||
|
||||
extern void __fini_cpp_exceptions(void) {
|
||||
@@ -39,10 +39,12 @@ extern void __fini_cpp_exceptions(void) {
|
||||
}
|
||||
}
|
||||
|
||||
extern void __init_cpp_exceptions(void) {
|
||||
if (fragmentID == -2) {
|
||||
fragmentID = __register_fragment(&_eti_init_info, GetR2());
|
||||
}
|
||||
asm char* GetR2(void) {
|
||||
#ifdef __MWERKS__ // clang-format off
|
||||
nofralloc
|
||||
mr r3, r2
|
||||
blr
|
||||
#endif // clang-format on
|
||||
}
|
||||
|
||||
__declspec(section ".ctors") extern void* const __init_cpp_exceptions_reference = __init_cpp_exceptions;
|
||||
|
||||
@@ -1,89 +1,87 @@
|
||||
#include "_mem.h"
|
||||
|
||||
__declspec(section ".init") void* memset(void* dst, int val, size_t size){
|
||||
__fill_mem(dst,val, size);
|
||||
__declspec(section ".init") void* memcpy(void* dst, const void* src, size_t size) {
|
||||
const unsigned char* s;
|
||||
unsigned char* d;
|
||||
|
||||
if ((unsigned long)src >= (unsigned long)dst) {
|
||||
s = (const unsigned char*)src - 1;
|
||||
d = (unsigned char*)dst - 1;
|
||||
size++;
|
||||
while (--size != 0) {
|
||||
*++d = *++s;
|
||||
}
|
||||
} else {
|
||||
s = (const unsigned char*)src + size;
|
||||
d = (unsigned char*)dst + size;
|
||||
size++;
|
||||
while (--size != 0) {
|
||||
*--d = *--s;
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
__declspec(section ".init") void __fill_mem(void* dst, int val, size_t n){
|
||||
u32 v = (u8) val;
|
||||
u32 i;
|
||||
|
||||
((u8 *) dst) = ((u8 *) dst) - 1;
|
||||
|
||||
if (n >= 32)
|
||||
{
|
||||
i = (~ (u32) dst) & 3;
|
||||
__declspec(section ".init") void __fill_mem(void* dst, int val, size_t n) {
|
||||
unsigned long v = (unsigned char)val;
|
||||
unsigned long i;
|
||||
|
||||
if (i) {
|
||||
n -= i;
|
||||
|
||||
do {
|
||||
*++(((u8 *) dst)) = v;
|
||||
} while (--i);
|
||||
}
|
||||
|
||||
if (v)
|
||||
v |= v << 24 | v << 16 | v << 8;
|
||||
|
||||
((u32 *) dst) = ((u32 *) (((u8 *) dst) + 1)) - 1;
|
||||
|
||||
i = n >> 5;
|
||||
|
||||
if (i) {
|
||||
do {
|
||||
*++((u32 *) dst) = v;
|
||||
*++((u32 *) dst) = v;
|
||||
*++((u32 *) dst) = v;
|
||||
*++((u32 *) dst) = v;
|
||||
*++((u32 *) dst) = v;
|
||||
*++((u32 *) dst) = v;
|
||||
*++((u32 *) dst) = v;
|
||||
*++((u32 *) dst) = v;
|
||||
} while (--i);
|
||||
}
|
||||
|
||||
i = (n & 31) >> 2;
|
||||
|
||||
if (i) {
|
||||
do {
|
||||
*++((u32 *) dst) = v;
|
||||
} while (--i);
|
||||
}
|
||||
|
||||
((u8 *) dst) = ((u8 *) (((u32 *) dst) + 1)) - 1;
|
||||
|
||||
n &= 3;
|
||||
}
|
||||
|
||||
if (n)
|
||||
do {
|
||||
*++((u8 *) dst) = v;
|
||||
} while (--n);
|
||||
|
||||
return;
|
||||
((unsigned char*)dst) = ((unsigned char*)dst) - 1;
|
||||
|
||||
if (n >= 32) {
|
||||
i = (~(unsigned long)dst) & 3;
|
||||
|
||||
if (i) {
|
||||
n -= i;
|
||||
|
||||
do {
|
||||
*++(((unsigned char*)dst)) = v;
|
||||
} while (--i);
|
||||
}
|
||||
|
||||
if (v)
|
||||
v |= v << 24 | v << 16 | v << 8;
|
||||
|
||||
((unsigned long*)dst) = ((unsigned long*)(((unsigned char*)dst) + 1)) - 1;
|
||||
|
||||
i = n >> 5;
|
||||
|
||||
if (i) {
|
||||
do {
|
||||
*++((unsigned long*)dst) = v;
|
||||
*++((unsigned long*)dst) = v;
|
||||
*++((unsigned long*)dst) = v;
|
||||
*++((unsigned long*)dst) = v;
|
||||
*++((unsigned long*)dst) = v;
|
||||
*++((unsigned long*)dst) = v;
|
||||
*++((unsigned long*)dst) = v;
|
||||
*++((unsigned long*)dst) = v;
|
||||
} while (--i);
|
||||
}
|
||||
|
||||
i = (n & 31) >> 2;
|
||||
|
||||
if (i) {
|
||||
do {
|
||||
*++((unsigned long*)dst) = v;
|
||||
} while (--i);
|
||||
}
|
||||
|
||||
((unsigned char*)dst) = ((unsigned char*)(((unsigned long*)dst) + 1)) - 1;
|
||||
|
||||
n &= 3;
|
||||
}
|
||||
|
||||
if (n)
|
||||
do {
|
||||
*++((unsigned char*)dst) = v;
|
||||
} while (--n);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
__declspec(section ".init") void* memcpy(void* dst, const void* src, size_t size){
|
||||
const u8* s;
|
||||
u8* d;
|
||||
__declspec(section ".init") void* memset(void* dst, int val, size_t size) {
|
||||
__fill_mem(dst, val, size);
|
||||
|
||||
if((u32)src >= (u32)dst){
|
||||
s = (const u8*)src -1;
|
||||
d = (u8*)dst -1;
|
||||
size++;
|
||||
while (--size !=0){
|
||||
*++d = *++s;
|
||||
}
|
||||
}
|
||||
else{
|
||||
s = (const u8*)src + size;
|
||||
d = (u8*)dst + size;
|
||||
size++;
|
||||
while (--size != 0){
|
||||
*--d = *--s;
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#include "stdarg.h"
|
||||
|
||||
void* __va_arg(va_list v_list, int type) {
|
||||
char* addr;
|
||||
char* reg = &(v_list->gpr);
|
||||
long g_reg = v_list->gpr;
|
||||
long maxsize = 8;
|
||||
long size = 4;
|
||||
long increment = 1;
|
||||
long even = 0;
|
||||
long fpr_offset = 0;
|
||||
long regsize = 4;
|
||||
|
||||
if (type == 3) {
|
||||
reg = &(v_list->fpr);
|
||||
g_reg = v_list->fpr;
|
||||
size = 8;
|
||||
fpr_offset = 32;
|
||||
regsize = 8;
|
||||
}
|
||||
if (type == 2) {
|
||||
size = 8;
|
||||
maxsize--;
|
||||
if (g_reg & 1)
|
||||
even = 1;
|
||||
increment = 2;
|
||||
}
|
||||
if (g_reg < maxsize) {
|
||||
g_reg += even;
|
||||
addr = v_list->reg_save_area + fpr_offset + (g_reg * regsize);
|
||||
*reg = g_reg + increment;
|
||||
} else {
|
||||
*reg = 8;
|
||||
addr = v_list->input_arg_area;
|
||||
addr = (char*)(((unsigned long)(addr) + ((size)-1)) & ~((size)-1));
|
||||
v_list->input_arg_area = addr + size;
|
||||
}
|
||||
if (type == 0)
|
||||
addr = *((char**)addr);
|
||||
|
||||
return addr;
|
||||
}
|
||||
@@ -6,15 +6,6 @@ typedef struct DestructorChain {
|
||||
|
||||
DestructorChain* __global_destructor_chain;
|
||||
|
||||
void __destroy_global_chain(void) {
|
||||
DestructorChain* gdc;
|
||||
|
||||
while ((gdc = __global_destructor_chain) != 0) {
|
||||
__global_destructor_chain = gdc->next;
|
||||
((void (*)(void*, short))gdc->destructor)(gdc->object, -1);
|
||||
}
|
||||
}
|
||||
|
||||
void* __register_global_object(void* object, void* destructor, void* regmem) {
|
||||
((DestructorChain*)regmem)->next = __global_destructor_chain;
|
||||
((DestructorChain*)regmem)->destructor = destructor;
|
||||
@@ -24,5 +15,13 @@ void* __register_global_object(void* object, void* destructor, void* regmem) {
|
||||
return object;
|
||||
}
|
||||
|
||||
__declspec(section ".dtors") static void* const __destroy_global_chain_reference =
|
||||
__destroy_global_chain;
|
||||
void __destroy_global_chain(void) {
|
||||
DestructorChain* gdc;
|
||||
|
||||
while ((gdc = __global_destructor_chain) != 0) {
|
||||
__global_destructor_chain = gdc->next;
|
||||
((void (*)(void*, short))gdc->destructor)(gdc->object, -1);
|
||||
}
|
||||
}
|
||||
|
||||
__declspec(section ".dtors") static void* const __destroy_global_chain_reference = __destroy_global_chain;
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
// presumably, ptmf = pointer to member function
|
||||
|
||||
typedef struct PTMF {
|
||||
long this_delta; // self-explanatory
|
||||
long v_offset; // vtable offset
|
||||
union {
|
||||
void* f_addr; // function address
|
||||
long ve_offset; // virtual function entry offset (of vtable)
|
||||
} f_data;
|
||||
} PTMF;
|
||||
|
||||
long __ptmf_test(PTMF* ptmf);
|
||||
void __ptmf_scall(...);
|
||||
|
||||
asm long __ptmf_test(register PTMF* ptmf)
|
||||
{
|
||||
#ifdef __MWERKS__ // clang-format off
|
||||
nofralloc
|
||||
lwz r5, PTMF.this_delta(r3)
|
||||
lwz r6, PTMF.v_offset(r3)
|
||||
lwz r7, PTMF.f_data(r3)
|
||||
li r3, 0x1
|
||||
cmpwi r5, 0
|
||||
cmpwi cr6, r6, 0
|
||||
cmpwi cr7, r7, 0
|
||||
bnelr-
|
||||
bnelr- cr6
|
||||
bnelr- cr7
|
||||
li r3, 0
|
||||
blr
|
||||
#endif // clang-format on
|
||||
}
|
||||
|
||||
asm void __ptmf_scall(...)
|
||||
{
|
||||
#ifdef __MWERKS__ // clang-format off
|
||||
nofralloc
|
||||
lwz r0, PTMF.this_delta(r12)
|
||||
lwz r11, PTMF.v_offset(r12)
|
||||
lwz r12, PTMF.f_data(r12)
|
||||
add r3, r3, r0
|
||||
cmpwi r11, 0
|
||||
blt- cr0, loc_0x20
|
||||
lwzx r12, r3, r12
|
||||
lwzx r12, r12, r11
|
||||
loc_0x20:
|
||||
mtctr r12
|
||||
bctr
|
||||
#endif // clang-format on
|
||||
}
|
||||
@@ -0,0 +1,875 @@
|
||||
#pragma ANSI_strict off
|
||||
#pragma tvectors off
|
||||
#pragma internal on
|
||||
|
||||
#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 __shr2i(void);
|
||||
asm void __cvt_sll_flt(void);
|
||||
asm void __cvt_dbl_usll(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 __constants[] = {
|
||||
0x00000000, 0x00000000, // 0.0
|
||||
0x41F00000, 0x00000000, // 2**32
|
||||
0x41E00000, 0x00000000, // 2**31
|
||||
};
|
||||
|
||||
asm unsigned __cvt_fp2unsigned(register double d) {
|
||||
#ifdef __MWERKS__ // clang-format off
|
||||
nofralloc
|
||||
stwu r1,-16(r1)
|
||||
lis r4, __constants@h
|
||||
ori 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
|
||||
#endif // clang-format on
|
||||
}
|
||||
|
||||
static asm void __save_fpr(void) {
|
||||
#ifdef __MWERKS__ // clang-format off
|
||||
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
|
||||
#endif // clang-format on
|
||||
}
|
||||
|
||||
static asm void __restore_fpr(void) {
|
||||
#ifdef __MWERKS__ // clang-format off
|
||||
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
|
||||
#endif // clang-format on
|
||||
}
|
||||
|
||||
static asm void __save_gpr(void) {
|
||||
#ifdef __MWERKS__ // clang-format off
|
||||
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
|
||||
#endif // clang-format on
|
||||
}
|
||||
|
||||
static asm void __restore_gpr(void) {
|
||||
#ifdef __MWERKS__ // clang-format off
|
||||
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
|
||||
#endif // clang-format on
|
||||
}
|
||||
|
||||
asm void __div2u(void) {
|
||||
#ifdef __MWERKS__ // clang-format off
|
||||
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
|
||||
#endif // clang-format on
|
||||
}
|
||||
|
||||
asm void __div2i(void) {
|
||||
#ifdef __MWERKS__ // clang-format off
|
||||
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
|
||||
#endif // clang-format on
|
||||
}
|
||||
|
||||
// Modulo for 64-bit ints
|
||||
// uses funky 2-register passing ABI
|
||||
// r3,r4 = r3,r4 % r5,r6
|
||||
asm void __mod2u(void) {
|
||||
#ifdef __MWERKS__ // clang-format off
|
||||
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
|
||||
#endif // clang-format on
|
||||
}
|
||||
|
||||
asm void __mod2i(void) {
|
||||
#ifdef __MWERKS__ // clang-format off
|
||||
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
|
||||
#endif // clang-format on
|
||||
}
|
||||
|
||||
asm void __shl2i(void) {
|
||||
#ifdef __MWERKS__ // clang-format off
|
||||
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
|
||||
#endif // clang-format on
|
||||
}
|
||||
|
||||
asm void __shr2u(void) {
|
||||
#ifdef __MWERKS__ // clang-format off
|
||||
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
|
||||
#endif // clang-format on
|
||||
}
|
||||
|
||||
asm void __shr2i(void) {
|
||||
#ifdef __MWERKS__ // clang-format off
|
||||
nofralloc
|
||||
subfic r8, r5, 0x20
|
||||
addic. r9, r5, -0x20
|
||||
srw r4, r4, r5
|
||||
slw r10, r3, r8
|
||||
or r4, r4, r10
|
||||
sraw r10, r3, r9
|
||||
ble around
|
||||
or r4, r4, r10
|
||||
around:
|
||||
sraw r3, r3, r5
|
||||
blr
|
||||
#endif // clang-format on
|
||||
}
|
||||
|
||||
asm void __cvt_ull_flt(void) {
|
||||
#ifdef __MWERKS__ // clang-format off
|
||||
nofralloc
|
||||
stwu r1, -0x10(r1)
|
||||
or. r7, r3, r4
|
||||
li r6, 0x0
|
||||
beq zero
|
||||
cntlzw r7, r3
|
||||
cntlzw r8, r4
|
||||
extlwi r9, r7, 5, 26
|
||||
srawi r9, r9, 31
|
||||
and r9, r9, r8
|
||||
add r7, r7, r9
|
||||
subfic r8, r7, 0x20
|
||||
addic r9, r7, -0x20
|
||||
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, 21
|
||||
cmpwi r7, 0x400
|
||||
addi r6, r6, 0x43e
|
||||
blt noround
|
||||
bgt round
|
||||
rlwinm. r7, r4, 0, 20, 20
|
||||
beq noround
|
||||
round:
|
||||
addic r4, r4, 0x800
|
||||
addze r3, r3
|
||||
addze r6, r6
|
||||
noround:
|
||||
rotrwi r4, r4, 11
|
||||
rlwimi r4, r3, 21, 0, 10
|
||||
extrwi r3, r3, 20, 1
|
||||
slwi r6, r6, 20
|
||||
or r3, r6, r3
|
||||
zero:
|
||||
stw r3, 0x8(r1)
|
||||
stw r4, 0xc(r1)
|
||||
lfd f1, 0x8(r1)
|
||||
frsp f1, f1
|
||||
addi r1, r1, 0x10
|
||||
blr
|
||||
#endif // clang-format on
|
||||
}
|
||||
|
||||
asm void __cvt_dbl_usll(void) {
|
||||
#ifdef __MWERKS__ // clang-format off
|
||||
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
|
||||
#endif // clang-format on
|
||||
}
|
||||
Reference in New Issue
Block a user