From a4e6192030dbf2b6a7a0137dd46ee1b34d1e4832 Mon Sep 17 00:00:00 2001 From: Tyler McGavran Date: Tue, 15 Feb 2022 01:40:33 -0500 Subject: [PATCH] Match one function, update mips_to_c of 2 others (#164) There's a function that appears to use continued fractions to approximate the value of tanh(x/2), which is super weird. Signed-off-by: Taggerung --- .../code_80091750/func_80091A6C.s | 27 ----- src/code_80091750.c | 99 ++++++++----------- src/code_80091750.h | 1 + 3 files changed, 44 insertions(+), 83 deletions(-) delete mode 100644 asm/non_matchings/code_80091750/func_80091A6C.s diff --git a/asm/non_matchings/code_80091750/func_80091A6C.s b/asm/non_matchings/code_80091750/func_80091A6C.s deleted file mode 100644 index b8138b337..000000000 --- a/asm/non_matchings/code_80091750/func_80091A6C.s +++ /dev/null @@ -1,27 +0,0 @@ -glabel func_80091A6C -/* 09266C 80091A6C 04C00006 */ bltz $a2, .L80091A88 -/* 092670 80091A70 3C013FE0 */ li $at, 0x3FE00000 # 1.750000 -/* 092674 80091A74 3C014000 */ li $at, 0x40000000 # 2.000000 -/* 092678 80091A78 44810800 */ mtc1 $at, $f1 -/* 09267C 80091A7C 44800000 */ mtc1 $zero, $f0 -/* 092680 80091A80 10000004 */ b .L80091A94 -/* 092684 80091A84 00000000 */ nop -.L80091A88: -/* 092688 80091A88 44810800 */ mtc1 $at, $f1 -/* 09268C 80091A8C 44800000 */ mtc1 $zero, $f0 -/* 092690 80091A90 00063023 */ negu $a2, $a2 -.L80091A94: -/* 092694 80091A94 10C00008 */ beqz $a2, .L80091AB8 -.L80091A98: -/* 092698 80091A98 30CE0001 */ andi $t6, $a2, 1 -/* 09269C 80091A9C 11C00003 */ beqz $t6, .L80091AAC -/* 0926A0 80091AA0 00067843 */ sra $t7, $a2, 1 -/* 0926A4 80091AA4 46206302 */ mul.d $f12, $f12, $f0 -/* 0926A8 80091AA8 00000000 */ nop -.L80091AAC: -/* 0926AC 80091AAC 46200002 */ mul.d $f0, $f0, $f0 -/* 0926B0 80091AB0 15E0FFF9 */ bnez $t7, .L80091A98 -/* 0926B4 80091AB4 01E03025 */ move $a2, $t7 -.L80091AB8: -/* 0926B8 80091AB8 03E00008 */ jr $ra -/* 0926BC 80091ABC 46206006 */ mov.d $f0, $f12 diff --git a/src/code_80091750.c b/src/code_80091750.c index 33d316cb1..4d08e7058 100644 --- a/src/code_80091750.c +++ b/src/code_80091750.c @@ -37,24 +37,21 @@ f64 exponent_by_squaring(f64 base, s32 exponent) { } #ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -f64 exponent_by_squaring(s32); // extern -f64 func_8009186C(f64); // extern -f64 func_8009195C(f64, f64); // extern -extern f64 D_800F0CB0; -extern f64 D_800F0CB8; +//generated by mips_to_c commit 06ada559d7a32fdab49fa2d619cdfa027615bcda +f64 func_8009186C(); /* extern */ +f64 func_8009195C(f64, f64); /* extern */ -f64 func_800917B0(f64 arg0, f64 arg1, f64 arg2) { +f64 func_800917B0(f64 arg0, ? arg0_lo, f64 arg1, ? arg1_lo, ? arg2_unk0, ? arg2_unk4) { s32 temp_f8; - f64 phi_a2; - phi_a2 = arg2; - if ((arg1 <= D_800F0CB0) && (D_800F0CB8 <= arg1) && (temp_f8 = arg1, phi_a2 = (bitwise f64) temp_f8, (arg1 == temp_f8))) { - return exponent_by_squaring(temp_f8); + if ((arg1 <= D_800F0CB0) && (arg1 >= D_800F0CB8)) { + temp_f8 = (s32) arg1; + if (arg1 == (f64) temp_f8) { + return exponent_by_squaring(arg0, temp_f8); + } } if (arg0 > 0.0) { - arg2 = arg1; - return func_8009195C(func_8009186C(phi_a2) * arg2, arg2); + return func_8009195C(func_8009186C() * arg1, arg1); } return 0.0; } @@ -107,70 +104,60 @@ GLOBAL_ASM("asm/non_matchings/code_80091750/func_8009186C.s") #endif #ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -? func_80091A6C(f64, f64, s32); // extern +//generated by mips_to_c commit 06ada559d7a32fdab49fa2d619cdfa027615bcda +// This is an f64 approximation of ln(2) extern f64 D_800F0CD0; - -void func_8009195C(f64 arg0) { +f64 func_8009195C(f64 arg0) { f64 temp_f14; - f64 temp_f18; f64 temp_f2; f64 temp_f2_2; s32 temp_f10; + f64 thing; if (arg0 >= 0.0) { - + thing = 0.5 + } else { + thing = -0.5 } - temp_f18 = D_800F0CD0; - temp_f10 = 0.0 + (arg0 / temp_f18); - temp_f14 = arg0 - (temp_f10 * temp_f18); + temp_f10 = (s32) (thing + (arg0 / D_800F0CD0)); + temp_f14 = arg0 - ((f64) temp_f10 * D_800F0CD0); temp_f2 = temp_f14 * temp_f14; - temp_f2_2 = 2.0 + (temp_f2 / (6 + (temp_f2 / (0xA + (temp_f2 / (0xE + (temp_f2 / (0x12 + (temp_f2 / 22.0))))))))); - func_80091A6C((temp_f2_2 + temp_f14) / (temp_f2_2 - temp_f14), temp_f14, temp_f10); + /** + * This is the denominator part a tanh(x/2) continued fraction, where temp_f14 is x + * The best reference to this I can find is: https://math.stackexchange.com/questions/3241906/continued-fraction-02-6-10-14-22n-1-frace-1e1 + **/ + temp_f2_2 = 2.0 + (temp_f2 / ((f64) 6 + (temp_f2 / ((f64) 0xA + (temp_f2 / ((f64) 0xE + (temp_f2 / ((f64) 0x12 + (temp_f2 / 22.0))))))))); + return func_80091A6C((temp_f2_2 + temp_f14) / (temp_f2_2 - temp_f14), temp_f10); } #else GLOBAL_ASM("asm/non_matchings/code_80091750/func_8009195C.s") #endif -#ifdef MIPS_TO_C -//generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 -f64 func_80091A6C(f64 arg0, s32 arg2) { - s32 temp_t7; - s32 phi_a2; - s32 phi_a2_2; - f64 phi_f12; - f64 phi_f12_2; - f64 phi_f12_3; - f64 phi_f0; - - phi_a2 = arg2; - phi_f12 = arg0; - phi_f12_3 = arg0; - if (arg2 >= 0) { +/** + * This function appears to multiply some `value` + * by 2 ^ `exponent`, even if that exponent is negative +**/ +f64 func_80091A6C(f64 value, s32 exponent) { + f64 base; + if (exponent >= 0) { + base = 2.0; } else { - phi_a2 = -arg2; + exponent = -exponent; + base = 0.5; } - phi_a2_2 = phi_a2; - phi_f0 = 0.0; - if (phi_a2 != 0) { + + if (exponent != 0) { do { - temp_t7 = phi_a2_2 >> 1; - phi_f12_2 = phi_f12_3; - if ((phi_a2_2 & 1) != 0) { - phi_f12_2 = phi_f12_3 * phi_f0; + if ((exponent & 1) != 0) { + value *= base; } - phi_a2_2 = temp_t7; - phi_f12 = phi_f12_2; - phi_f12_3 = phi_f12_2; - phi_f0 *= phi_f0; - } while (temp_t7 != 0); + exponent >>= 1; + base *= base; + } while (exponent != 0); } - return phi_f12; + return value; } -#else -GLOBAL_ASM("asm/non_matchings/code_80091750/func_80091A6C.s") -#endif #ifdef MIPS_TO_C //generated by mips_to_c commit 3c3b0cede1a99430bfd3edf8d385802b94f91307 diff --git a/src/code_80091750.h b/src/code_80091750.h index ce9b2874e..2582d22fc 100644 --- a/src/code_80091750.h +++ b/src/code_80091750.h @@ -47,6 +47,7 @@ typedef struct { /* Function Prototypes */ f64 exponent_by_squaring(f64, s32); +f64 func_80091A6C(f64, s32); void swap_values(s32*, s32*); void func_80092148(); void func_800921B4();