From cefe919b8d39cb5b60d79b1dc7452e80abdf9657 Mon Sep 17 00:00:00 2001 From: TakaRikka <38417346+TakaRikka@users.noreply.github.com> Date: Wed, 24 Dec 2025 16:54:21 -0800 Subject: [PATCH] msl_c mostly matching for wii/shield (#2994) --- config/ShieldD/splits.txt | 3 +- configure.py | 7 +- include/global.h | 7 +- src/JSystem/JKernel/JKRFileLoader.cpp | 13 +- .../MSL/MSL_C++/MSL_Common/Include/cstdint.h | 2 + .../MSL/MSL_C/MSL_Common/Include/ansi_files.h | 6 +- .../MSL/MSL_C/MSL_Common/Include/cmath.h | 72 +- .../MSL_Common/Include/critical_regions.h | 10 +- .../MSL/MSL_C/MSL_Common/Include/ctype.h | 137 +++- .../MSL/MSL_C/MSL_Common/Include/errno.h | 2 + .../MSL/MSL_C/MSL_Common/Include/float.h | 17 + .../MSL/MSL_C/MSL_Common/Include/locale.h | 114 +++ .../MSL/MSL_C/MSL_Common/Include/mbstring.h | 3 + .../MSL/MSL_C/MSL_Common/Include/strtold.h | 15 + .../MSL/MSL_C/MSL_Common/Include/strtoul.h | 2 + .../MSL/MSL_C/MSL_Common/Include/wctype_api.h | 32 + .../MSL/MSL_C/MSL_Common/Include/wstring.h | 21 + .../MSL/MSL_C/MSL_Common/Src/FILE_POS.c | 54 +- .../MSL/MSL_C/MSL_Common/Src/alloc.c | 52 +- .../MSL/MSL_C/MSL_Common/Src/ansi_files.c | 2 + .../MSL/MSL_C/MSL_Common/Src/arith.c | 4 + .../MSL/MSL_C/MSL_Common/Src/char_io.c | 41 +- .../MSL/MSL_C/MSL_Common/Src/ctype.c | 89 +- .../MSL/MSL_C/MSL_Common/Src/direct_io.c | 22 + .../MSL/MSL_C/MSL_Common/Src/extras.c | 4 +- .../MSL/MSL_C/MSL_Common/Src/file_io.c | 4 +- .../MSL/MSL_C/MSL_Common/Src/float.c | 7 +- .../MSL/MSL_C/MSL_Common/Src/locale.c | 122 +++ .../MSL/MSL_C/MSL_Common/Src/math_api.c | 51 ++ .../MSL/MSL_C/MSL_Common/Src/math_double.c | 7 + .../MSL/MSL_C/MSL_Common/Src/mbstring.c | 133 +-- .../MSL/MSL_C/MSL_Common/Src/mem.c | 16 +- .../MSL/MSL_C/MSL_Common/Src/mem_funcs.c | 12 + .../MSL/MSL_C/MSL_Common/Src/printf.c | 378 ++++++++- .../MSL/MSL_C/MSL_Common/Src/scanf.c | 769 ++++++++++++++++++ .../MSL/MSL_C/MSL_Common/Src/secure_error.c | 16 + .../MSL/MSL_C/MSL_Common/Src/signal.c | 10 +- .../MSL/MSL_C/MSL_Common/Src/string.c | 13 +- .../MSL/MSL_C/MSL_Common/Src/strtold.c | 663 +++++++++++++++ .../MSL/MSL_C/MSL_Common/Src/strtoul.c | 136 ++++ .../MSL/MSL_C/MSL_Common/Src/wchar_io.c | 41 +- .../MSL/MSL_C/MSL_Common/Src/wctype.c | 166 ++++ .../MSL/MSL_C/MSL_Common/Src/wstring.c | 44 + .../Math/Double_precision/e_acos.c | 5 + .../Math/Double_precision/e_asin.c | 5 + .../Math/Double_precision/e_fmod.c | 21 +- .../Math/Double_precision/e_log.c | 161 ++++ .../Math/Double_precision/e_log10.c | 99 +++ .../Math/Double_precision/e_pow.c | 617 +++++++------- .../Math/Double_precision/e_rem_pio2.c | 240 +++--- .../Math/Double_precision/k_rem_pio2.c | 2 +- .../Math/Double_precision/s_ldexp.c | 8 + .../Math/Double_precision/w_log10.c | 28 + .../MSL_Common_Embedded/Math/Include/fdlibm.h | 4 +- .../MSL_C/MSL_Common_Embedded/Src/ansi_fp.c | 168 +++- .../MSL_C/MSL_Common_Embedded/Src/math_sun.c | 13 + .../MSL_C/PPC_EABI/Src/abort_exit_ppc_eabi.c | 0 .../MSL/MSL_C/PPC_EABI/Src/math_ppc.c | 2 + 58 files changed, 3997 insertions(+), 695 deletions(-) create mode 100644 src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/locale.h create mode 100644 src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/strtold.h create mode 100644 src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/wctype_api.h create mode 100644 src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/wstring.h create mode 100644 src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/locale.c create mode 100644 src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/math_api.c create mode 100644 src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/math_double.c create mode 100644 src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/secure_error.c create mode 100644 src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/strtold.c create mode 100644 src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/wctype.c create mode 100644 src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/wstring.c create mode 100644 src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c create mode 100644 src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log10.c create mode 100644 src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log10.c create mode 100644 src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Src/math_sun.c create mode 100644 src/PowerPC_EABI_Support/MSL/MSL_C/PPC_EABI/Src/abort_exit_ppc_eabi.c diff --git a/config/ShieldD/splits.txt b/config/ShieldD/splits.txt index 65b2639c8d..4aa788274e 100644 --- a/config/ShieldD/splits.txt +++ b/config/ShieldD/splits.txt @@ -4609,7 +4609,7 @@ PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/printf.c: .sdata2 start:0x80752ED0 end:0x80752ED8 PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/float.c: - .sdata start:0x8074C238 end:0x8074C24C + .sdata start:0x8074C238 end:0x8074C248 PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/scanf.c: .text start:0x80621C6C end:0x80623150 @@ -4890,6 +4890,7 @@ TRK_MINNOW_DOLPHIN/debugger/embedded/MetroTRK/Os/dolphin/target_options.c: NdevExi2AD/DebuggerDriver.c: .text start:0x8062ECBC end:0x8062F1EC + .sdata start:0x8074C248 end:0x8074C24C .sbss start:0x8074D728 end:0x8074D73C NdevExi2AD/exi2.c: diff --git a/configure.py b/configure.py index 1cdcf6c728..a749467ee5 100755 --- a/configure.py +++ b/configure.py @@ -306,10 +306,13 @@ cflags_runtime = [ "-str reuse,pool,readonly", "-common off", "-char signed", - # "-inline deferred,auto" + "-func_align 4", + "-DMSL_USE_INLINES=1", ] -if config.version not in ["ShieldD", "Shield"]: +if config.version in ["RZDE01_00", "RZDE01_02", "RZDP01", "RZDJ01", "ShieldD", "Shield"]: + cflags_runtime.extend(["-ipa file", "-fp_contract off"]) +else: cflags_runtime.extend(["-inline deferred,auto"]) cflags_trk = [ diff --git a/include/global.h b/include/global.h index bd726e2e07..ab207f43d3 100644 --- a/include/global.h +++ b/include/global.h @@ -31,6 +31,8 @@ #define DEBUG 0 #endif +#define MSL_INLINE inline + #define ARRAY_SIZE(o) (s32)(sizeof(o) / sizeof(o[0])) #define ARRAY_SIZEU(o) (sizeof(o) / sizeof(o[0])) @@ -87,11 +89,6 @@ void* __memcpy(void*, const void*, int); #define POINTER_ADD(ptr_, offset_) POINTER_ADD_TYPE(__typeof__(ptr_), ptr_, offset_) // floating-point constants -#define _HUGE_ENUF 1e+300 -#define INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF)) -#define HUGE_VAL ((double)INFINITY) -#define HUGE_VALL ((long double)INFINITY) -#define DOUBLE_INF HUGE_VAL static const float INF = 2000000000.0f; // hack to make strings with no references compile properly diff --git a/src/JSystem/JKernel/JKRFileLoader.cpp b/src/JSystem/JKernel/JKRFileLoader.cpp index 8a96cafceb..0fd148394e 100644 --- a/src/JSystem/JKernel/JKRFileLoader.cpp +++ b/src/JSystem/JKernel/JKRFileLoader.cpp @@ -1,6 +1,9 @@ #include "JSystem/JSystem.h" // IWYU pragma: keep #include "JSystem/JKernel/JKRFileLoader.h" + +#define MSL_USE_INLINES 1 // needed to inline tolower call. not inlined elsewhere in the repo + #include "string.h" #include "ctype.h" #include "global.h" @@ -122,15 +125,7 @@ const char* JKRFileLoader::fetchVolumeName(char* buffer, s32 bufferSize, const c path++; while (*path != 0 && *path != '/') { if (1 < bufferSize) { - int lower_char; - int ch = (int)*path; - if (ch == -1) { - lower_char = -1; - } else { - lower_char = __lower_map[ch & 0xFF]; - } - - *buffer = lower_char; + *buffer = tolower(*path); buffer++; bufferSize--; } diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/cstdint.h b/src/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/cstdint.h index 5f6672b452..e9530a60b8 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/cstdint.h +++ b/src/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/cstdint.h @@ -20,6 +20,8 @@ typedef long long int64_t; typedef uint32_t uintptr_t; typedef int32_t intptr_t; +typedef long long intmax_t; + #ifdef __cplusplus }; } diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ansi_files.h b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ansi_files.h index 6ad791a935..ce7410884c 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ansi_files.h +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ansi_files.h @@ -28,9 +28,9 @@ enum __file_kinds { }; enum __file_orientation { - /* 0x0 */ UNORIENTED, - /* 0x1 */ CHAR_ORIENTED, - /* 0x2 */ WIDE_ORIENTED, + __unoriented, + __char_oriented, + __wide_oriented }; typedef struct _file_modes { diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cmath.h b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cmath.h index ad501c896f..78fd149109 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cmath.h +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cmath.h @@ -6,6 +6,10 @@ #define NAN (*(float*) __float_nan) #define HUGE_VALF (*(float*) __float_huge) +#if !PLATFORM_GCN +#define HUGE_VAL (*(double*)__double_huge) +#endif + #define M_PI 3.14159265358979323846f #define M_SQRT3 1.73205f @@ -44,34 +48,65 @@ float sinf(float); double sqrt(double); double tan(double); float tanf(float); - -inline float expf(float x) { - return exp(x); -} - -inline float ceilf(float num) { - return ceil(num); -} +double log10(double); inline double fabs(double f) { return __fabs(f); } -inline float fabsf(float f) { - return (float)fabs((double)f); +inline long double fabsl(long double x) { + return fabs((double)x); } -inline float floorf(float num) { + + +MSL_INLINE float acosf(float x) { + return acos(x); +} + +MSL_INLINE float atan2f(float y, float x) { + return (float)atan2(y, x); +} + +MSL_INLINE float ceilf(float num) { + return ceil(num); +} + +MSL_INLINE float cosf(float x) { + return cos(x); +} + +MSL_INLINE float expf(float x) { + return exp(x); +} + +MSL_INLINE float floorf(float num) { return floor(num); } -inline float fmodf(float f1, float f2) { +MSL_INLINE float powf(float x, float y) { + return pow(x, y); +} + +MSL_INLINE float sinf(float x) { + return sin(x); +} + +MSL_INLINE float fabsf(float f) { + return (float)fabs((double)f); +} + +MSL_INLINE float fmodf(float f1, float f2) { return fmod(f1, f2); } +MSL_INLINE float log10f(float x) { + return log10(x); +} + #include "global.h" #if PLATFORM_WII || PLATFORM_SHIELD -inline float sqrtf(float mag) { +MSL_INLINE float sqrtf(float mag) { return sqrt(mag); } #else @@ -87,7 +122,7 @@ inline float sqrtf(float mag) { static double _half = 0.5; static double _three = 3.0; #endif -inline float sqrtf(float mag) { +MSL_INLINE float sqrtf(float mag) { #ifndef DECOMPCTX // part of the same hack, these are defined outside of the function when using decompctx static const double _half = 0.5; @@ -110,15 +145,10 @@ inline float sqrtf(float mag) { } #endif -inline float atan2f(float y, float x) { - return (float)atan2(y, x); +MSL_INLINE float tanf(float x) { + return tan(x); } -inline float sinf(float x) { return sin(x); } -inline float cosf(float x) { return cos(x); } -inline float tanf(float x) { return tan(x); } -inline float acosf(float x) { return acos(x); } - #ifdef __cplusplus }; #endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/critical_regions.h b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/critical_regions.h index a36c75d6c7..ed219e8d64 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/critical_regions.h +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/critical_regions.h @@ -1,6 +1,8 @@ #ifndef _MSL_COMMON_CRITICAL_REGIONS_H #define _MSL_COMMON_CRITICAL_REGIONS_H +#include "global.h" + #ifdef __cplusplus extern "C" { #endif @@ -20,11 +22,17 @@ enum critical_regions { void __init_critical_regions(void); void __kill_critical_regions(void); + +#if PLATFORM_GCN void __begin_critical_region(int region); void __end_critical_region(int region); +#else +#define __begin_critical_region(region) +#define __end_critical_region(region) +#endif #ifdef __cplusplus } #endif -#endif \ No newline at end of file +#endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ctype.h b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ctype.h index 867dc71d91..a0f28e735c 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ctype.h +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ctype.h @@ -1,12 +1,15 @@ #ifndef _MSL_COMMON_CTYPE_H #define _MSL_COMMON_CTYPE_H +#include "global.h" + #ifdef __cplusplus extern "C" { #endif #define EOF -1L +#if PLATFORM_GCN extern unsigned char __ctype_map[]; extern unsigned char __lower_map[]; extern unsigned char __upper_map[]; @@ -28,19 +31,135 @@ extern unsigned char __upper_map[]; #define __control (__motion_char | __control_char) #define __zero_fill(c) ((int)(unsigned char)(c)) -int tolower(int); - -inline int isalpha(int c) { return (int)(__ctype_map[(unsigned char)c] & __letter); } -inline int isdigit(int c) { return (int)(__ctype_map[(unsigned char)c] & __digit); } -inline int isspace(int c) { return (int)(__ctype_map[(unsigned char)c] & __whitespace); } -inline int isupper(int c) { return (int)(__ctype_map[(unsigned char)c] & __upper_case); } -inline int isxdigit(int c) { return (int)(__ctype_map[(unsigned char)c] & __hex_digit); } // added underscore to avoid naming conflicts inline int _tolower(int c) { return (c == -1 ? -1 : (int)__lower_map[(unsigned char)c]); } -inline int toupper(int c) { return (c == -1 ? -1 : (int)__upper_map[(unsigned char)c]); } +#else +#include + +extern const unsigned char __lower_mapC[0x100]; +extern const unsigned char __upper_mapC[0x100]; +extern const unsigned short __ctype_mapC[0x100]; + +#define ctype_alpha 0x0001 +#define ctype_blank 0x0002 +#define ctype_cntrl 0x0004 +#define ctype_digit 0x0008 +#define ctype_graph 0x0010 +#define ctype_lower 0x0020 +#define ctype_print 0x0040 +#define ctype_punct 0x0080 +#define ctype_space 0x0100 +#define ctype_upper 0x0200 +#define ctype_xdigit 0x0400 + +#define ctype_alnum (ctype_alpha | ctype_digit) + +#endif + +int tolower(int); + +#if MSL_USE_INLINES +MSL_INLINE int isalnum(int c) { + #if !PLATFORM_GCN + return (c < 0 || c >= 256) ? 0 : (int)(_current_locale.ctype_cmpt_ptr->ctype_map_ptr[c] & ctype_alnum); + #endif +} + +MSL_INLINE int isalpha(int c) { + #if PLATFORM_GCN + return (int)(__ctype_map[(unsigned char)c] & __letter); + #else + return (c < 0 || c >= 256) ? 0 : (int)(_current_locale.ctype_cmpt_ptr->ctype_map_ptr[c] & ctype_alpha); + #endif +} + +MSL_INLINE int isblank(int c) { + #if !PLATFORM_GCN + return (c < 0 || c >= 256) ? 0 : (int)(_current_locale.ctype_cmpt_ptr->ctype_map_ptr[c] & ctype_blank); + #endif +} + +MSL_INLINE int iscntrl(int c) { + #if !PLATFORM_GCN + return (c < 0 || c >= 256) ? 0 : (int)(_current_locale.ctype_cmpt_ptr->ctype_map_ptr[c] & ctype_cntrl); + #endif +} + +MSL_INLINE int isdigit(int c) { + #if PLATFORM_GCN + return (int)(__ctype_map[(unsigned char)c] & __digit); + #else + return (c < 0 || c >= 256) ? 0 : (int)(_current_locale.ctype_cmpt_ptr->ctype_map_ptr[c] & ctype_digit); + #endif +} + +MSL_INLINE int isgraph(int c) { + #if !PLATFORM_GCN + return (c < 0 || c >= 256) ? 0 : (int)(_current_locale.ctype_cmpt_ptr->ctype_map_ptr[c] & ctype_graph); + #endif +} + +MSL_INLINE int islower(int c) { + #if !PLATFORM_GCN + return (c < 0 || c >= 256) ? 0 : (int)(_current_locale.ctype_cmpt_ptr->ctype_map_ptr[c] & ctype_lower); + #endif +} + +MSL_INLINE int isprint(int c) { + #if !PLATFORM_GCN + return (c < 0 || c >= 256) ? 0 : (int)(_current_locale.ctype_cmpt_ptr->ctype_map_ptr[c] & ctype_print); + #endif +} + +MSL_INLINE int ispunct(int c) { + #if !PLATFORM_GCN + return (c < 0 || c >= 256) ? 0 : (int)(_current_locale.ctype_cmpt_ptr->ctype_map_ptr[c] & ctype_punct); + #endif +} + +MSL_INLINE int isupper(int c) { + #if PLATFORM_GCN + return (int)(__ctype_map[(unsigned char)c] & __upper_case); + #else + return (c < 0 || c >= 256) ? 0 : (int)(_current_locale.ctype_cmpt_ptr->ctype_map_ptr[c] & ctype_upper); + #endif +} + +MSL_INLINE int isxdigit(int c) { + #if PLATFORM_GCN + return (int)(__ctype_map[(unsigned char)c] & __hex_digit); + #else + return (c < 0 || c >= 256) ? 0 : (int)(_current_locale.ctype_cmpt_ptr->ctype_map_ptr[c] & ctype_xdigit); + #endif +} + +MSL_INLINE int isspace(int c) { + #if PLATFORM_GCN + return (int)(__ctype_map[(unsigned char)c] & __whitespace); + #else + return (c < 0 || c >= 256) ? 0 : (int)(_current_locale.ctype_cmpt_ptr->ctype_map_ptr[c] & ctype_space); + #endif +} + +MSL_INLINE int tolower(int c) { + #if PLATFORM_GCN + return (c == -1) ? -1 : (int) (__lower_map[(unsigned char)c]); + #else + return ((c < 0) || (c >= 0x100)) ? c : (int) (_current_locale.ctype_cmpt_ptr->lower_map_ptr[c]); + #endif +} + +MSL_INLINE int toupper(int c) { + #if PLATFORM_GCN + return (c == -1 ? -1 : (int)__upper_map[(unsigned char)c]); + #else + return (c < 0 || c >= 256) ? c : (int)(&_current_locale)->ctype_cmpt_ptr->upper_map_ptr[c]; + #endif +} +#endif #ifdef __cplusplus } #endif -#endif /* _MSL_COMMON_CTYPE_H */ \ No newline at end of file +#endif /* _MSL_COMMON_CTYPE_H */ diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/errno.h b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/errno.h index 1826b92e75..d66024d2a7 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/errno.h +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/errno.h @@ -1,6 +1,8 @@ #ifndef MSL_COMMON_SRC_ERRNO_H #define MSL_COMMON_SRC_ERRNO_H +#include "global.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/float.h b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/float.h index ad2e24f96d..1a294cbb1c 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/float.h +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/float.h @@ -2,6 +2,7 @@ #define _MSL_COMMON_FLOAT_H #include +#include "global.h" #define FP_SNAN 0 #define FP_QNAN 1 @@ -22,6 +23,7 @@ ((sizeof(x) == sizeof(float)) ? __fpclassifyf((float)(x)) : \ __fpclassifyd((double)(x)) ) #endif + #define signbit(x) ((sizeof(x) == sizeof(float)) ? __signbitf(x) : __signbitd(x)) #define isfinite(x) ((fpclassify(x) > FP_INFINITE)) #define isnan(x) (fpclassify(x) == FP_NAN) @@ -37,6 +39,10 @@ extern int __float_huge[]; extern int __float_max[]; extern int __float_epsilon[]; +#if !PLATFORM_GCN +extern int __double_huge[]; +#endif + #ifdef __cplusplus extern "C" { #endif @@ -108,4 +114,15 @@ int __fpclassifyl(long double __value); #define DBL_MAX_EXP 1024 #define DBL_MAX_10_EXP 308 +#define LDBL_MANT_DIG 53 +#define LDBL_DIG 15 +#define LDBL_MIN_EXP (-1021) +#define LDBL_MIN_10_EXP (-308) +#define LDBL_MAX_EXP 1024 +#define LDBL_MAX_10_EXP 308 + +#define LDBL_MAX 0x1.fffffffffffffP1023L +#define LDBL_EPSILON 0x1.0000000000000P-52L +#define LDBL_MIN 0x1.0000000000000P-1022L + #endif /* _MSL_COMMON_FLOAT_H */ diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/locale.h b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/locale.h new file mode 100644 index 0000000000..fa317f2837 --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/locale.h @@ -0,0 +1,114 @@ +#ifndef _MSL_LOCALE_H +#define _MSL_LOCALE_H + +#include + +typedef int (*__decode_mbyte) (wchar_t*, const char*, size_t); +typedef int (*__encode_mbyte) (char*, wchar_t); + +struct lconv { + char* decimal_point; + char* thousands_sep; + char* grouping; + char* mon_decimal_point; + char* mon_thousands_sep; + char* mon_grouping; + char* positive_sign; + char* negative_sign; + char* currency_symbol; + char frac_digits; + char p_cs_precedes; + char n_cs_precedes; + char p_sep_by_space; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; + char* int_curr_symbol; + char int_frac_digits; + char int_p_cs_precedes; + char int_n_cs_precedes; + char int_p_sep_by_space; + char int_n_sep_by_space; + char int_p_sign_posn; + char int_n_sign_posn; +}; + +struct _loc_mon_cmpt { + char CmptName[8]; + char* mon_decimal_point; + char* mon_thousands_sep; + char* mon_grouping; + char* positive_sign; + char* negative_sign; + char* currency_symbol; + char frac_digits; + char p_cs_precedes; + char n_cs_precedes; + char p_sep_by_space; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; + char* int_curr_symbol; + char int_frac_digits; + char int_p_cs_precedes; + char int_n_cs_precedes; + char int_p_sep_by_space; + char int_n_sep_by_space; + char int_p_sign_posn; + char int_n_sign_posn; +}; + +struct _loc_num_cmpt { + char CmptName[8]; + char* decimal_point; + char* thousands_sep; + char* grouping; +}; + +struct _loc_time_cmpt { + char CmptName[8]; + const char* am_pm; + const char* DateTime_Format; + const char* Twelve_hr_format; + const char* Date_Format; + const char* Time_Format; + const char* Day_Names; + const char* MonthNames; + char* TimeZone; +}; + +struct _loc_coll_cmpt { + char name[8]; + int char_start; + int char_coll_tab_size; + short char_spec; + unsigned short* char_coll_table_ptr; + unsigned short* wchar_coll_seq_ptr; +}; + +struct _loc_ctype_cmpt { + char name[8]; // 0x0 + const unsigned short* ctype_map_ptr; // 0x8 + const unsigned char* upper_map_ptr; // 0xC + const unsigned char* lower_map_ptr; // 0x10 + const unsigned short* wctype_map_ptr; // 0x14 + const wchar_t* wupper_map_ptr; // 0x18 + const wchar_t* wlower_map_ptr; // 0x1C + __decode_mbyte decode_mb; + __encode_mbyte encode_wc; +}; + +struct __locale { + struct __locale* next_locale; // 0x0 + char name[0x30]; // 0x4 + struct _loc_coll_cmpt* coll_cmpt_ptr; // 0x34 + struct _loc_ctype_cmpt* ctype_cmpt_ptr; // 0x38 + struct _loc_mon_cmpt* mon_cmpt_ptr; // 0x3C + struct _loc_num_cmpt* num_cmpt_ptr; // 0x40 + struct _loc_time_cmpt* time_cmpt_ptr; // 0x44 +}; + +extern struct __locale _current_locale; +extern struct lconv __lconv; + +#endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/mbstring.h b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/mbstring.h index 8b0a236ec0..5936adcc6c 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/mbstring.h +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/mbstring.h @@ -9,6 +9,9 @@ extern "C" { size_t wcstombs(char* dst, const wchar_t* src, size_t n); +int __mbtowc_noconv(wchar_t*, const char*, size_t); +int __wctomb_noconv(char*, wchar_t); + #ifdef __cplusplus } #endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/strtold.h b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/strtold.h new file mode 100644 index 0000000000..cc73532cd1 --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/strtold.h @@ -0,0 +1,15 @@ +#ifndef MSL_STRTOLD_H +#define MSL_STRTOLD_H + +#ifdef __cplusplus +extern "C" { +#endif + +long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* ReadProcArg, int* chars_scanned, + int* overflow); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/strtoul.h b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/strtoul.h index 7d637f763b..a5d93ece23 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/strtoul.h +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/strtoul.h @@ -9,6 +9,8 @@ long strtol(const char* str, char** end, int base); unsigned long strtoul(const char* str, char** end, int base); unsigned long __strtoul(int base, int max_width, int (*ReadProc)(void*, int, int), void* ReadProcArg, int* chars_scanned, int* negative, int* overflow); +unsigned long long __strtoull(int base, int max_width, int (*ReadProc)(void*, int, int), void* ReadProcArg, + int* chars_scanned, int* negative, int* overflow); int atoi(const char* str); float atof(const char* str); diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/wctype_api.h b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/wctype_api.h new file mode 100644 index 0000000000..fd011d70d1 --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/wctype_api.h @@ -0,0 +1,32 @@ +#ifndef _MSL_WCTYPE_H +#define _MSL_WCTYPE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define wctype_alpha 0x0001 +#define wctype_blank 0x0002 +#define wctype_cntrl 0x0004 +#define wctype_digit 0x0008 +#define wctype_graph 0x0010 +#define wctype_lower 0x0020 +#define wctype_print 0x0040 +#define wctype_punct 0x0080 +#define wctype_space 0x0100 +#define wctype_upper 0x0200 +#define wctype_xdigit 0x0400 + +#define wctype_alnum (wctype_alpha | wctype_digit) + +extern const unsigned short __wctype_mapC[256]; +extern const wchar_t __wlower_mapC[256]; +extern const wchar_t __wupper_mapC[256]; + +#ifdef __cplusplus +} +#endif + +#endif /* _MSL_COMMON_CTYPE_H */ diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/wstring.h b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/wstring.h new file mode 100644 index 0000000000..7cd6e26b55 --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/wstring.h @@ -0,0 +1,21 @@ +#ifndef MSL_WSTRING_H +#define MSL_WSTRING_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +size_t wcslen(const wchar_t*); +wchar_t* wcscpy(wchar_t*, const wchar_t*); +wchar_t* wcsncpy(wchar_t*, const wchar_t*, size_t); +wchar_t* wcscat(wchar_t*, const wchar_t*); +int wcscmp(const wchar_t*, const wchar_t*); +wchar_t* wcschr(const wchar_t*, wchar_t); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/FILE_POS.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/FILE_POS.c index 6c9275730e..a4edf4c5fd 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/FILE_POS.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/FILE_POS.c @@ -2,15 +2,6 @@ #include "critical_regions.h" #include "errno.h" -long ftell(FILE* stream) { - int retval; - - __begin_critical_region(stdin_access); - retval = (long)_ftell(stream); - __end_critical_region(stdin_access); - return retval; -} - int _ftell(FILE* file) { int charsInUndoBuffer = 0; int position; @@ -43,12 +34,18 @@ int _ftell(FILE* file) { return (position); } +long ftell(FILE* stream) { + int retval; + + __begin_critical_region(stdin_access); + retval = (long)_ftell(stream); + __end_critical_region(stdin_access); + return retval; +} + int _fseek(FILE* file, unsigned long offset, int whence) { int bufferCode; int pos; - int adjust; - unsigned long state; - int buffLen; unsigned char* ptr; @@ -68,38 +65,7 @@ int _fseek(FILE* file, unsigned long offset, int whence) { if (whence == SEEK_CUR) { whence = SEEK_SET; - adjust = 0; - if ((file->file_mode.file_kind != 1 && file->file_mode.file_kind != 2) || - file->file_state.error != 0) - { - errno = 0x28; - pos = -1; - } else { - state = file->file_state.io_state; - if (state == 0) { - pos = file->position; - } else { - pos = file->buffer_position; - ptr = file->buffer; - buffLen = (file->buffer_ptr - ptr); - pos += buffLen; - if ((state >= 3)) { - adjust = (state - 2); - pos -= adjust; - } - - if (file->file_mode.binary_io == 0) { - int i; - for (i = (buffLen - adjust); i != 0; i--) { - unsigned char c = *ptr; - ptr++; - if (c == 10) { - pos++; - } - } - } - } - } + pos = _ftell(file); offset += pos; } diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/alloc.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/alloc.c index c06fb26075..a50c8913aa 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/alloc.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/alloc.c @@ -2,6 +2,8 @@ #include "critical_regions.h" #include +#include "global.h" + typedef struct Block { struct Block* prev; struct Block* next; @@ -124,7 +126,29 @@ static const unsigned long fix_pool_sizes[] = {4, 12, 20, 36, 52, 68}; void __sys_free(); -static inline SubBlock* SubBlock_merge_prev(SubBlock* ths, SubBlock** start) { +void Block_link(Block* ths, SubBlock* sb) { + SubBlock** st; + SubBlock_set_free(sb); + st = &Block_start(ths); + + if (*st != 0) { + sb->prev = (*st)->prev; + sb->prev->next = sb; + sb->next = *st; + (*st)->prev = sb; + *st = sb; + *st = SubBlock_merge_prev(*st, st); + SubBlock_merge_next(*st, st); + } else { + *st = sb; + sb->prev = sb; + sb->next = sb; + } + if (ths->max_size < SubBlock_size(*st)) + ths->max_size = SubBlock_size(*st); +} + +static SubBlock* SubBlock_merge_prev(SubBlock* ths, SubBlock** start) { unsigned long prevsz; SubBlock* p; @@ -144,7 +168,7 @@ static inline SubBlock* SubBlock_merge_prev(SubBlock* ths, SubBlock** start) { return ths; } -static inline void SubBlock_merge_next(SubBlock* pBlock, SubBlock** pStart) { +static void SubBlock_merge_next(SubBlock* pBlock, SubBlock** pStart) { SubBlock* next_sub_block; unsigned long this_cur_size; @@ -179,29 +203,7 @@ static inline void SubBlock_merge_next(SubBlock* pBlock, SubBlock** pStart) { } } -inline void Block_link(Block* ths, SubBlock* sb) { - SubBlock** st; - SubBlock_set_free(sb); - st = &Block_start(ths); - - if (*st != 0) { - sb->prev = (*st)->prev; - sb->prev->next = sb; - sb->next = *st; - (*st)->prev = sb; - *st = sb; - *st = SubBlock_merge_prev(*st, st); - SubBlock_merge_next(*st, st); - } else { - *st = sb; - sb->prev = sb; - sb->next = sb; - } - if (ths->max_size < SubBlock_size(*st)) - ths->max_size = SubBlock_size(*st); -} - -static inline Block* __unlink(__mem_pool_obj* pool_obj, Block* bp) { +static Block* __unlink(__mem_pool_obj* pool_obj, Block* bp) { Block* result = bp->next; if (result == bp) { result = 0; diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/ansi_files.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/ansi_files.c index 55116eb5e9..e5e725311c 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/ansi_files.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/ansi_files.c @@ -1,6 +1,8 @@ #include "ansi_files.h" #include "critical_regions.h" +#include "global.h" + static unsigned char stdin_buff[0x100]; static unsigned char stdout_buff[0x100]; diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/arith.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/arith.c index 3d72a9263b..ecb47761d5 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/arith.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/arith.c @@ -7,6 +7,10 @@ int abs(int n) { return (n); } +long labs(long __x) { + return __x > 0 ? __x : -__x; +} + div_t div(int numerator, int denominator) { div_t ret; int i = 1; diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/char_io.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/char_io.c index c480f2745d..0fdc6ed150 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/char_io.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/char_io.c @@ -3,6 +3,8 @@ #include "misc_io.h" #include "wchar_io.h" +#include "global.h" + int __put_char(int c, FILE* stream) { int ret; @@ -18,8 +20,15 @@ int __put_char(int c, FILE* stream) { } if (stream->file_state.io_state == __neutral && (stream->file_mode.io_mode & __write)) { - if ((stream->file_mode.io_mode & __append) && fseek(stream, 0, 2) != 0) { - return 0; + if ((stream->file_mode.io_mode & __append)) { + #if PLATFORM_GCN + if (fseek(stream, 0, 2) != 0) + #else + if (_fseek(stream, 0, 2) != 0) + #endif + { + return 0; + } } stream->file_state.io_state = __writing; @@ -61,31 +70,21 @@ exit: return ret; } +#if PLATFORM_GCN +#define __putc(c, file) \ + ((fwide(file, -1) >= 0) ? -1 : (file)->buffer_length-- ? (int) (*(file)->buffer_ptr++ = (unsigned char)(c)) : __put_char(c, file)) +#else +#define __putc(c, file) \ + ((__fwide(file, -1) >= 0) ? -1 : (file)->buffer_length-- ? (int) (*(file)->buffer_ptr++ = (unsigned char)(c)) : __put_char(c, file)) +#endif + int fputs(const char* s, FILE* stream) { char c; - int var_r3; - unsigned long len; int ret = 0; __begin_critical_region(stdin_access); while (c = *s++, c != 0) { - if (fwide(stream, -1) >= 0) { - var_r3 = -1; - } else { - len = stream->buffer_length; - stream->buffer_length = len - 1; - - if (len != 0) { - char* buf = (char*)stream->buffer_ptr; - stream->buffer_ptr++; - - *buf = var_r3 = c & 0xFF; - } else { - var_r3 = __put_char(c, stream); - } - } - - if (var_r3 == -1) { + if (__putc(c, stream) == -1) { ret = -1; break; } diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/ctype.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/ctype.c index 556432dc7b..4bc8cd4a7e 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/ctype.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/ctype.c @@ -1,5 +1,15 @@ + +#include "locale.h" + +#include "global.h" + +// necessary to generate symbols in this TU +#undef MSL_INLINE +#define MSL_INLINE __declspec(weak) + #include "ctype.h" +#if PLATFORM_GCN #define ctrl __control_char #define motn __motion_char #define spac __space_char @@ -46,16 +56,6 @@ unsigned char __lower_map[256] = { // clang-format on }; -int tolower(int __c) { - { - if (__c == -1) { - return 0xffffffff; - } - - return (unsigned int)__lower_map[__c & 0xff]; - } -} - unsigned char __upper_map[256] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, @@ -75,3 +75,72 @@ unsigned char __upper_map[256] = { 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, // clang-format on }; +#else +#define alph ctype_alpha +#define blnk ctype_blank +#define cntl ctype_cntrl +#define digi ctype_digit | ctype_graph | ctype_print +#define grph ctype_graph +#define lowc ctype_lower | ctype_alpha | ctype_graph | ctype_print +#define prnt ctype_print +#define punc ctype_punct | ctype_graph | ctype_print +#define spac ctype_space +#define uppc ctype_upper | ctype_alpha | ctype_graph | ctype_print +#define hexd ctype_xdigit +#define dhex hexd | digi +#define uhex hexd | uppc +#define lhex hexd | lowc +#define ctbl cntl | blnk +#define ctsp cntl | spac +#define sblp spac | blnk | prnt +#define csbl cntl | spac | blnk + +const unsigned short __ctype_mapC[256] = { + cntl, cntl, cntl, cntl, cntl, cntl, cntl, cntl, cntl, csbl, ctsp, ctsp, ctsp, ctsp, cntl, cntl, + cntl, cntl, cntl, cntl, cntl, cntl, cntl, cntl, cntl, cntl, cntl, cntl, cntl, cntl, cntl, cntl, + sblp, punc, punc, punc, punc, punc, punc, punc, punc, punc, punc, punc, punc, punc, punc, punc, + dhex, dhex, dhex, dhex, dhex, dhex, dhex, dhex, dhex, dhex, punc, punc, punc, punc, punc, punc, + punc, uhex, uhex, uhex, uhex, uhex, uhex, uppc, uppc, uppc, uppc, uppc, uppc, uppc, uppc, uppc, + uppc, uppc, uppc, uppc, uppc, uppc, uppc, uppc, uppc, uppc, uppc, punc, punc, punc, punc, punc, + punc, lhex, lhex, lhex, lhex, lhex, lhex, lowc, lowc, lowc, lowc, lowc, lowc, lowc, lowc, lowc, + lowc, lowc, lowc, lowc, lowc, lowc, lowc, lowc, lowc, lowc, lowc, punc, punc, punc, punc, cntl +}; + +const unsigned char __lower_mapC[0x100] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', + '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '[', '\\', ']', '^', '_', + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', 0x7F, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF +}; + +const unsigned char __upper_mapC[0x100] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', + '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', + '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{', '|', '}', '~', 0x7F, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF +}; +#endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/direct_io.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/direct_io.c index d4edd12dc3..e4a2baa3ab 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/direct_io.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/direct_io.c @@ -36,7 +36,11 @@ size_t __fwrite(const void* buffer, size_t size, size_t count, FILE* stream) { if (stream->file_state.io_state == __neutral) { if (stream->file_mode.io_mode & __write) { if (stream->file_mode.io_mode & __append) { + #if PLATFORM_GCN if (fseek(stream, 0, SEEK_END)) + #else + if (_fseek(stream, 0, SEEK_END)) + #endif return 0; } stream->file_state.io_state = __writing; @@ -63,6 +67,7 @@ size_t __fwrite(const void* buffer, size_t size, size_t count, FILE* stream) { if (num_bytes > bytes_to_go) num_bytes = bytes_to_go; + if (stream->file_mode.buffer_mode == _IOLBF && num_bytes) if ((newline = (unsigned char*)__memrchr(write_ptr, '\n', num_bytes)) != NULL) num_bytes = newline + 1 - write_ptr; @@ -71,12 +76,15 @@ size_t __fwrite(const void* buffer, size_t size, size_t count, FILE* stream) { memcpy(stream->buffer_ptr, write_ptr, num_bytes); write_ptr += num_bytes; + #if PLATFORM_GCN bytes_written += num_bytes; + #endif bytes_to_go -= num_bytes; stream->buffer_ptr += num_bytes; stream->buffer_length -= num_bytes; } + if (!stream->buffer_length || newline != NULL || (stream->file_mode.buffer_mode == _IONBF)) { @@ -88,6 +96,9 @@ size_t __fwrite(const void* buffer, size_t size, size_t count, FILE* stream) { break; } } + #if !PLATFORM_GCN + bytes_written += num_bytes; + #endif } while (bytes_to_go && always_buffer); } @@ -99,10 +110,17 @@ size_t __fwrite(const void* buffer, size_t size, size_t count, FILE* stream) { stream->buffer_size = bytes_to_go; stream->buffer_ptr = write_ptr + bytes_to_go; + #if PLATFORM_GCN if (__flush_buffer(stream, &num_bytes) != __no_io_error) set_error(stream); bytes_written += num_bytes; + #else + if (__flush_buffer(stream, &num_bytes) != __no_io_error) + set_error(stream); + else + bytes_written += num_bytes; + #endif stream->buffer = save_buffer; stream->buffer_size = save_size; @@ -115,5 +133,9 @@ size_t __fwrite(const void* buffer, size_t size, size_t count, FILE* stream) { if (stream->file_mode.buffer_mode != _IOFBF) stream->buffer_length = 0; + #if PLATFORM_GCN return ((bytes_written + size - 1) / size); + #else + return bytes_written / size; + #endif } diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/extras.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/extras.c index f7e9fd4c80..d24ac7b5ea 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/extras.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/extras.c @@ -6,8 +6,8 @@ int stricmp(const char* str1, const char* str2) { char b_var; do { - b_var = _tolower(*str1++); - a_var = _tolower(*str2++); + b_var = tolower(*str1++); + a_var = tolower(*str2++); if (b_var < a_var) { return -1; diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/file_io.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/file_io.c index df816b2b45..fe71593f35 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/file_io.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/file_io.c @@ -72,8 +72,8 @@ int __msl_strnicmp(const char* str1, const char* str2, int n) { char c1, c2; for (i = 0; i < n; i++) { - c1 = _tolower(*str1++); - c2 = _tolower(*str2++); + c1 = tolower(*str1++); + c2 = tolower(*str2++); if (c1 < c2) { return -1; diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/float.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/float.c index 5abb35f27c..473150f84f 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/float.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/float.c @@ -1,15 +1,16 @@ #include "float.h" +#include "global.h" int __float_nan[] = {0x7FFFFFFF}; int __float_huge[] = {0x7F800000}; -#if !__REVOLUTION_SDK__ +#if PLATFORM_GCN int __float_max[] = {0x7F7FFFFF}; int __float_epsilon[] = {0x34000000}; #endif -#if DEBUG -unsigned long long __double_huge[] = {0x7ff0000000000000ULL}; +#if !PLATFORM_GCN +int __double_huge[] = {0x7FF00000, 0}; #endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/locale.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/locale.c new file mode 100644 index 0000000000..3826686f22 --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/locale.c @@ -0,0 +1,122 @@ +#include +#include +#include +#include + +#pragma options align=native +#pragma warn_padding off + +struct lconv __lconv = { + ".", + "", + "", + "", + "", + "", + "", + "", + "", + 0x7F, + 0x7F, + 0x7F, + 0x7F, + 0x7F, + 0x7F, + 0x7F, + "", + 0x7F, + 0x7F, + 0x7F, + 0x7F, + 0x7F, + 0x7F, + 0x7F +}; +#pragma warn_padding reset +#pragma options align=reset + +struct _loc_ctype_cmpt _loc_ctyp_C = { + "C", + &__ctype_mapC[0], + &__upper_mapC[0], + &__lower_mapC[0], + &__wctype_mapC[0], + &__wupper_mapC[0], + &__wlower_mapC[0], + __mbtowc_noconv, + __wctomb_noconv +}; + +unsigned short char_coll_tableC[] = { + 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10, + 0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x11,0x12,0x13,0x14,0x15,0x16, + 0x17,0x2B,0x2D,0x2F,0x31,0x33,0x35,0x37,0x39,0x3B,0x3D,0x3F,0x41,0x43,0x45,0x47, + 0x49,0x4B,0x4D,0x4F,0x51,0x53,0x55,0x57,0x59,0x5B,0x5D,0x18,0x19,0x1A,0x1B,0x1C, + 0x00,0x2C,0x2E,0x30,0x32,0x34,0x36,0x38,0x3A,0x3C,0x3E,0x40,0x42,0x44,0x46,0x48, + 0x4A,0x4C,0x4E,0x50,0x52,0x54,0x56,0x58,0x5A,0x5C,0x5E,0x1D,0x1E,0x1F,0x20,0x00 +}; + +struct _loc_coll_cmpt _loc_coll_C = { + "C", + 0x20, + 0x6E, + 0, + char_coll_tableC, + NULL +}; + +struct _loc_mon_cmpt _loc_mon_C = { + "C", + "", + "", + "", + "", + "", + "", + 0x7F, + 0x7F, + 0x7F, + 0x7F, + 0x7F, + 0x7F, + 0x7F, + "", + 0x7F, + 0x7F, + 0x7F, + 0x7F, + 0x7F, + 0x7F, + 0x7F +}; + + +struct _loc_num_cmpt _loc_num_C = { + "C", + ".", + "", + "", +}; + +struct _loc_time_cmpt _loc_tim_C = { + "C", + "AM|PM", + "%a %b %e %T %Y", + "%I:%M:%S %p", + "%m/%d/%y", + "%T", + "Sun|Sunday|Mon|Monday|Tue|Tuesday|Wed|Wednesday|Thu|Thursday|Fri|Friday|Sat|Saturday", + "Jan|January|Feb|February|Mar|March|Apr|April|May|May|Jun|June|Jul|July|Aug|August|Sep|September|Oct|October|Nov|November|Dec|December", + "" +}; + + +struct __locale _current_locale = { + NULL, + "C", + &_loc_coll_C, + &_loc_ctyp_C, + &_loc_mon_C, + &_loc_num_C, + &_loc_tim_C +}; diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/math_api.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/math_api.c new file mode 100644 index 0000000000..6c9c5d05cc --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/math_api.c @@ -0,0 +1,51 @@ +// I think this TU didn't include the header or used a different header +// allowing for both the inline definition and these symbols to exist + +#define __HI(x) *(int*)&x +#define __LO(x) *(1 + (int*)&x) +#define __HIp(x) *(int*)x +#define __LOp(x) *(1 + (int*)x) + +int __fpclassifyf(float x) { + switch ((*(long*)&x) & 0x7f800000) { + case 0x7f800000: { + if ((*(long*)&x) & 0x007fffff) + return 1; + else + return 2; + break; + } + case 0: { + if ((*(long*)&x) & 0x007fffff) + return 5; + else + return 3; + break; + } + } + return 4; +} + +int __signbitd(double x) { + return __HI(x) & 0x80000000; +} + +int __fpclassifyd(double x) { + switch (__HI(x) & 0x7ff00000) { + case 0x7ff00000: { + if ((__HI(x) & 0x000fffff) || (__LO(x) & 0xffffffff)) + return 1; + else + return 2; + break; + } + case 0: { + if ((__HI(x) & 0x000fffff) || (__LO(x) & 0xffffffff)) + return 5; + else + return 3; + break; + } + } + return 4; +} diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/math_double.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/math_double.c new file mode 100644 index 0000000000..690e3dd71c --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/math_double.c @@ -0,0 +1,7 @@ +#include "global.h" + +// necessary to generate symbols in this TU +#undef MSL_INLINE +#define MSL_INLINE __declspec(weak) + +#include diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mbstring.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mbstring.c index d4daab1605..17e30a364e 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mbstring.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mbstring.c @@ -1,64 +1,103 @@ #include "mbstring.h" #include "cstring.h" +#include + +#include "global.h" + +#if !PLATFORM_GCN +int mbtowc(wchar_t* pwc, const char* s, size_t n) { + return _current_locale.ctype_cmpt_ptr->decode_mb(pwc, s, n); +} +#endif inline static int unicode_to_UTF8(char* s, wchar_t wchar) { - int number_of_bytes; - wchar_t wide_char; - char* target_ptr; - char first_byte_mark[4] = { 0x00, 0x00, 0xc0, 0xe0 }; + int number_of_bytes; + wchar_t wide_char; + char* target_ptr; + char first_byte_mark[4] = { 0x00, 0x00, 0xc0, 0xe0 }; - if (!s) - return (0); + if (!s) + return (0); - wide_char = wchar; - if (wide_char < 0x0080) - number_of_bytes = 1; - else if (wide_char < 0x0800) - number_of_bytes = 2; - else - number_of_bytes = 3; + wide_char = wchar; + if (wide_char < 0x0080) + number_of_bytes = 1; + else if (wide_char < 0x0800) + number_of_bytes = 2; + else + number_of_bytes = 3; - target_ptr = s + number_of_bytes; + target_ptr = s + number_of_bytes; - switch (number_of_bytes) { - case 3: - *--target_ptr = (wide_char & 0x003f) | 0x80; - wide_char >>= 6; - case 2: - *--target_ptr = (wide_char & 0x003f) | 0x80; - wide_char >>= 6; - case 1: - *--target_ptr = wide_char | first_byte_mark[number_of_bytes]; - } + switch (number_of_bytes) { + case 3: + *--target_ptr = (wide_char & 0x003f) | 0x80; + wide_char >>= 6; + case 2: + *--target_ptr = (wide_char & 0x003f) | 0x80; + wide_char >>= 6; + case 1: + *--target_ptr = wide_char | first_byte_mark[number_of_bytes]; + } - return number_of_bytes; + return number_of_bytes; } -inline int wctomb(char* s, wchar_t wchar) { return (unicode_to_UTF8(s, wchar)); } +int __mbtowc_noconv(wchar_t* pwc, const char* s, size_t n) { + if (!s) + return 0; + + if (!n) + return -1; + + if (pwc) + *pwc = (unsigned char)*s; + + if (!*s) + return(0); + + return 1; +} + +int __wctomb_noconv(char* s, wchar_t wchar) { + if (!s) + return 0; + + *s = wchar; + return 1; +} + +int wctomb(char* s, wchar_t wchar) { + #if PLATFORM_GCN + return (unicode_to_UTF8(s, wchar)); + #else + return _current_locale.ctype_cmpt_ptr->encode_wc(s, wchar); + #endif +} size_t wcstombs(char* s, const wchar_t* pwcs, size_t n) { - int chars_written = 0; - int result; - char temp[3]; - wchar_t* source; + int chars_written = 0; + int result; + char temp[3]; + wchar_t* source; - if (!s || !pwcs) - return (0); + if (!s || !pwcs) + return (0); - source = (wchar_t*)pwcs; - while (chars_written <= n) { - if (!*source) { - *(s + chars_written) = '\0'; - break; - } else { - result = wctomb(temp, *source++); - if ((chars_written + result) <= n) { - strncpy(s + chars_written, temp, result); - chars_written += result; - } else - break; - } - } + source = (wchar_t*)pwcs; + while (chars_written <= n) { + if (!*source) { + *(s + chars_written) = '\0'; + break; + } else { + result = wctomb(temp, *source++); + if ((chars_written + result) <= n) { + strncpy(s + chars_written, temp, result); + chars_written += result; + } else + break; + } + } - return chars_written; + return chars_written; } diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mem.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mem.c index 07f69f33b4..f2ea575cce 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mem.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mem.c @@ -1,8 +1,8 @@ #include "cstring.h" void* memmove(void* dst, const void* src, size_t n) { - unsigned char* csrc; - unsigned char* cdst; + const char* csrc; + char* cdst; int reverse = (unsigned int)src < (unsigned int)dst; @@ -24,19 +24,11 @@ void* memmove(void* dst, const void* src, size_t n) { return dst; } else { if (!reverse) { - csrc = ((unsigned char*)src) - 1; - cdst = ((unsigned char*)dst) - 1; - n++; - - while (--n > 0) { + for (csrc = (const char*)src - 1, cdst = (char*)dst - 1, n++; --n;){ *++cdst = *++csrc; } } else { - csrc = (unsigned char*)src + n; - cdst = (unsigned char*)dst + n; - n++; - - while (--n > 0) { + for (csrc = (const char*)src + n, cdst = (char*)dst + n, n++; --n;){ *--cdst = *--csrc; } } diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mem_funcs.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mem_funcs.c index f06bc3c306..b30da21f4b 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mem_funcs.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mem_funcs.c @@ -1,5 +1,7 @@ #include "mem_funcs.h" +#include "global.h" + #define cps ((unsigned char*)src) #define cpd ((unsigned char*)dst) #define lps ((unsigned long*)src) @@ -188,6 +190,11 @@ void __copy_longs_rev_unaligned(void* dst, const void* src, size_t n) { cps += 4 - src_offset; + #if !PLATFORM_GCN + cps = ((unsigned char *) lps); + cpd = ((unsigned char *) lpd); + #endif + i = n >> 3; v1 = *--lps; @@ -206,6 +213,11 @@ void __copy_longs_rev_unaligned(void* dst, const void* src, size_t n) { n &= 3; + #if !PLATFORM_GCN + cps = ((unsigned char *) lps); + cpd = ((unsigned char *) lpd); + #endif + if (n) { cps += src_offset; do diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/printf.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/printf.c index a737596dd9..0c2856e046 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/printf.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/printf.c @@ -3,10 +3,14 @@ #include "critical_regions.h" #include "ctype.h" #include "scanf.h" +#include "cmath.h" #include "cstdio.h" #include "cstring.h" +#include "cstdint.h" #include "wchar_io.h" +#define LDBL_MANT_DIG 53 + #define TARGET_FLOAT_BITS 64 #define TARGET_FLOAT_BYTES (TARGET_FLOAT_BITS / 8) #define TARGET_FLOAT_MAX_EXP LDBL_MAX_EXP @@ -28,8 +32,18 @@ enum argument_options { short_argument, long_argument, long_long_argument, + #if PLATFORM_GCN long_double_argument, - wchar_argument + #endif + wchar_argument, + + intmax_argument, + size_t_argument, + ptrdiff_argument, + + #if !PLATFORM_GCN + long_double_argument, + #endif }; typedef struct { @@ -154,12 +168,21 @@ static const char* parse_format(const char* format_string, va_list* arg, print_f f.argument_options = long_long_argument; c = *++s; } - break; - case 'L': f.argument_options = long_double_argument; break; +#if !PLATFORM_GCN + case 'j': + f.argument_options = intmax_argument; + break; + case 't': + f.argument_options = ptrdiff_argument; + break; + case 'z': + f.argument_options = size_t_argument; + break; +#endif default: flag_found = 0; break; @@ -192,7 +215,14 @@ static const char* parse_format(const char* format_string, va_list* arg, print_f case 'f': case 'F': - if (f.argument_options == short_argument || f.argument_options == long_long_argument) { + if (f.argument_options == short_argument + #if !PLATFORM_GCN + || f.argument_options == intmax_argument + || f.argument_options == size_t_argument + || f.argument_options == ptrdiff_argument + #endif + || f.argument_options == long_long_argument) + { f.conversion_char = 0xFF; break; } @@ -208,8 +238,14 @@ static const char* parse_format(const char* format_string, va_list* arg, print_f f.precision = 0xD; } - if (f.argument_options == short_argument || f.argument_options == long_long_argument || - f.argument_options == char_argument) + if (f.argument_options == short_argument + #if !PLATFORM_GCN + || f.argument_options == intmax_argument + || f.argument_options == size_t_argument + || f.argument_options == ptrdiff_argument + #endif + || f.argument_options == long_long_argument + || f.argument_options == char_argument) { f.conversion_char = 0xFF; } @@ -224,8 +260,14 @@ static const char* parse_format(const char* format_string, va_list* arg, print_f case 'e': case 'E': - if (f.argument_options == short_argument || f.argument_options == long_long_argument || - f.argument_options == char_argument) + if (f.argument_options == short_argument + #if !PLATFORM_GCN + || f.argument_options == intmax_argument + || f.argument_options == size_t_argument + || f.argument_options == ptrdiff_argument + #endif + || f.argument_options == long_long_argument + || f.argument_options == char_argument) { f.conversion_char = 0xFF; break; @@ -303,7 +345,11 @@ static char* long2str(signed long num, char* buff, print_format format) { base = 10; if (num < 0) { - unsigned_num = -unsigned_num; + #if !PLATFORM_GCN + if (num != 0x8000000000000000L) + #endif + unsigned_num = -unsigned_num; + minus = 1; } break; @@ -405,7 +451,11 @@ static char* longlong2str(signed long long num, char* pBuf, print_format fmt) { base = 10; if (num < 0) { - unsigned_num = -unsigned_num; + #if !PLATFORM_GCN + if (num != 0x8000000000000000LL) + #endif + unsigned_num = -unsigned_num; + minus = 1; } break; @@ -486,6 +536,7 @@ static char* longlong2str(signed long long num, char* pBuf, print_format fmt) { } static char* double2hex(long double num, char* buff, print_format format) { + #if PLATFORM_GCN int offset, what_nibble = 0; char* wrk_byte_ptr; char *p, *q; @@ -611,6 +662,175 @@ static char* double2hex(long double num, char* buff, print_format format) { } return p; +#else + char *p; + unsigned char *q; + unsigned char working_byte; + long double ld; + int expbits, expmask; + unsigned snum; + long exp; + print_format exp_format; + int hex_precision; + int mantissa_bit; + decform form; + decimal dec; + int radix_marker; + + radix_marker = *(unsigned char *)(__lconv).decimal_point; + p = buff; + ld = num; + + if (format.precision > 509) { + return 0; + } + + form.style = (char)0; + form.digits = 0x20; + __num2dec(&form, num, &dec); + + switch(*dec.sig.text){ + case '0': + dec.exp = 0; + break; + case 'I': + if (dec.sign) { + p = buff - 5; + if (format.conversion_char == 'A') strcpy(p, "-INF"); + else strcpy(p, "-inf"); + } + else { + p = buff - 4; + if (format.conversion_char == 'A') strcpy(p, "INF"); + else strcpy(p, "inf"); + } + + return p; + case 'N': + if (dec.sign) { + p = buff - 5; + if (format.conversion_char == 'A') strcpy(p, "-NAN"); + else strcpy(p, "-nan"); + } + else { + p = buff - 4; + if (format.conversion_char == 'A') strcpy(p, "NAN"); + else strcpy(p, "nan"); + } + + return p; + } + + exp_format.justification_options = right_justification; + exp_format.sign_options = sign_always; + exp_format.precision_specified = 0; + exp_format.alternate_form = 0; + exp_format.argument_options = normal_argument; + exp_format.field_width = 0; + exp_format.precision = 1; + exp_format.conversion_char = 'd'; + + expbits = 11; + expmask = 0x7FF; + + snum = ((unsigned char *)&num)[0] << 25; + if (TARGET_FLOAT_EXP_BITS > 7) + snum |= ((unsigned char *)&num)[1] << 17; + if (TARGET_FLOAT_EXP_BITS > 15) + snum |= ((unsigned char *)&num)[2] << 9; + if (TARGET_FLOAT_EXP_BITS > 23) + snum |= ((unsigned char *)&num)[3] << 1; + + snum = (snum >> (32 - expbits)) & expmask; + + if(snum != 0) + exp = snum - 0x3FF; + else + exp = 0; + + p = long2str(exp, buff, exp_format); + if (format.conversion_char == 'a') + *--p = 'p'; + else + *--p = 'P'; + q = (unsigned char *)# + + if (TARGET_FLOAT_IMPLICIT_J_BIT) { + mantissa_bit = (1 + expbits + format.precision * 4) - 1; + } + else { + mantissa_bit = (1 + expbits + format.precision * 4) - 4; + } + + for (hex_precision = format.precision; hex_precision >= 1; hex_precision--) { + if (mantissa_bit < 64) { + int mantissa_byte; + + mantissa_byte = mantissa_bit >> 3; + working_byte = (*(q + mantissa_byte)) >> (7 - (mantissa_bit & 7)); + + if ((mantissa_bit & ~7) != ((mantissa_bit - 4) & ~7)) { + working_byte |= (unsigned char)(((*(q + (mantissa_byte - 1))) << 8) >> (7 - ((mantissa_bit) & 7))); + } + + if (!TARGET_FLOAT_IMPLICIT_J_BIT) { + if (mantissa_bit == 1 + expbits) { + *--p = radix_marker; + working_byte &= 0x1; + } + } + + if ((working_byte &= 0xF) < 10) { + working_byte += (unsigned char)'0'; + } + else + if (format.conversion_char == 'a') { + working_byte += (unsigned char)('a' - 10); + } + else { + working_byte += (unsigned char)('A' - 10); + } + } + else { + working_byte = '0'; + } + + *--p = working_byte; + mantissa_bit -= 4; + } + + if (TARGET_FLOAT_IMPLICIT_J_BIT){ + if (format.precision || format.alternate_form) { + *--p = radix_marker; + } + + if(fabsl(ld) != 0.0) + *--p = '1'; + else + *--p = '0'; + } + + if (format.conversion_char == 'a') { + *--p = 'x'; + } + else { + *--p = 'X'; + } + + *--p = '0'; + + if (dec.sign) { + *--p = '-'; + } + else if (format.sign_options == sign_always) { + *--p = '+'; + } + else if (format.sign_options == space_holder) { + *--p = ' '; + } + + return p; + #endif } static void round_decimal(decimal* dec, int new_length) { @@ -675,7 +895,11 @@ static char* float2str(long double num, char* buff, print_format format) { int int_digits, frac_digits; int radix_marker; + #if PLATFORM_GCN radix_marker = '.'; + #else + radix_marker = *(unsigned char*)__lconv.decimal_point; + #endif if (format.precision > 509) { return 0; @@ -736,7 +960,12 @@ static char* float2str(long double num, char* buff, print_format format) { return p; } - dec.exp += dec.sig.length - 1; + #if PLATFORM_GCN + dec.exp += (dec.sig.length - 1); + #else + dec.exp += (short)(dec.sig.length - 1); + #endif + p = buff; *--p = 0; @@ -888,7 +1117,12 @@ static char* float2str(long double num, char* buff, print_format format) { } static int __pformatter(void* (*WriteProc)(void*, const char*, size_t), void* WriteProcArg, - const char* format_str, va_list arg) { + const char* format_str, va_list arg + #if !PLATFORM_GCN + ,int is_secure + #endif + ) +{ int num_chars, chars_written, field_width; const char* format_ptr; const char* curr_format; @@ -933,7 +1167,19 @@ static int __pformatter(void* (*WriteProc)(void*, const char*, size_t), void* Wr long_num = va_arg(arg, signed long); } else if (format.argument_options == long_long_argument) { long_long_num = va_arg(arg, signed long long); - } else { + } + #if !PLATFORM_GCN + else if (format.argument_options == intmax_argument) { + long_long_num = va_arg(arg, intmax_t); + } + else if (format.argument_options == size_t_argument) { + long_num = va_arg(arg, size_t); + } + else if (format.argument_options == ptrdiff_argument) { + long_num = va_arg(arg, ptrdiff_t); + } + #endif + else { long_num = va_arg(arg, int); } @@ -945,7 +1191,12 @@ static int __pformatter(void* (*WriteProc)(void*, const char*, size_t), void* Wr long_num = (signed char)long_num; } - if ((format.argument_options == long_long_argument)) { + if ((format.argument_options == long_long_argument) + #if !PLATFORM_GCN + || format.argument_options == intmax_argument + #endif + ) + { if (!(buff_ptr = longlong2str(long_long_num, buff + 512, format))) { goto conversion_error; } @@ -966,7 +1217,19 @@ static int __pformatter(void* (*WriteProc)(void*, const char*, size_t), void* Wr long_num = va_arg(arg, unsigned long); } else if (format.argument_options == long_long_argument) { long_long_num = va_arg(arg, signed long long); - } else { + } + #if !PLATFORM_GCN + else if (format.argument_options == intmax_argument) { + long_long_num = va_arg(arg, intmax_t); + } + else if (format.argument_options == size_t_argument) { + long_num = va_arg(arg, size_t); + } + else if (format.argument_options == ptrdiff_argument) { + long_num = va_arg(arg, ptrdiff_t); + } + #endif + else { long_num = va_arg(arg, unsigned int); } @@ -978,7 +1241,12 @@ static int __pformatter(void* (*WriteProc)(void*, const char*, size_t), void* Wr long_num = (unsigned char)long_num; } - if ((format.argument_options == long_long_argument)) { + if ((format.argument_options == long_long_argument) + #if !PLATFORM_GCN + || format.argument_options == intmax_argument + #endif + ) + { if (!(buff_ptr = longlong2str(long_long_num, buff + 512, format))) { goto conversion_error; } @@ -1029,6 +1297,13 @@ static int __pformatter(void* (*WriteProc)(void*, const char*, size_t), void* Wr if (format.argument_options == wchar_argument) { wchar_t* wcs_ptr = va_arg(arg, wchar_t*); + #if !PLATFORM_GCN + if (is_secure && wcs_ptr == NULL){ + __msl_runtime_constraint_violation_s(0,0,-1); + return -1; + } + #endif + if (wcs_ptr == NULL) { wcs_ptr = L""; } @@ -1042,6 +1317,13 @@ static int __pformatter(void* (*WriteProc)(void*, const char*, size_t), void* Wr buff_ptr = va_arg(arg, char*); } + #if !PLATFORM_GCN + if (is_secure && buff_ptr == NULL){ + __msl_runtime_constraint_violation_s(0,0,-1); + return -1; + } + #endif + if (buff_ptr == NULL) { buff_ptr = ""; } @@ -1067,6 +1349,13 @@ static int __pformatter(void* (*WriteProc)(void*, const char*, size_t), void* Wr case 'n': buff_ptr = va_arg(arg, char*); + #if !PLATFORM_GCN + if (is_secure){ + __msl_runtime_constraint_violation_s(0,0,-1); + return -1; + } + #endif + switch (format.argument_options) { case normal_argument: *(int*)buff_ptr = chars_written; @@ -1077,6 +1366,17 @@ static int __pformatter(void* (*WriteProc)(void*, const char*, size_t), void* Wr case long_argument: *(signed long*)buff_ptr = chars_written; break; + #if !PLATFORM_GCN + case intmax_argument: + *(intmax_t*)buff_ptr = chars_written; + break; + case size_t_argument: + *(size_t*)buff_ptr = chars_written; + break; + case ptrdiff_argument: + *(ptrdiff_t*)buff_ptr = chars_written; + break; + #endif case long_long_argument: *(signed long long*)buff_ptr = chars_written; break; @@ -1126,6 +1426,18 @@ static int __pformatter(void* (*WriteProc)(void*, const char*, size_t), void* Wr num_chars--; } + #if !PLATFORM_GCN + if ((format.justification_options == zero_fill) && ((format.conversion_char == 'a') || (format.conversion_char == 'A'))) + { + if (num_chars < 2) + return(-1); + if ((*WriteProc)(WriteProcArg, buff_ptr, 2) == 0) + return(-1); + num_chars -= 2; + buff_ptr += 2; + } + #endif + while (field_width < format.field_width) { if ((*WriteProc)(WriteProcArg, &fill_char, 1) == 0) { return -1; @@ -1158,7 +1470,11 @@ static int __pformatter(void* (*WriteProc)(void*, const char*, size_t), void* Wr } static void* __FileWrite(void* pFile, const char* pBuffer, size_t char_num) { + #if PLATFORM_GCN return (fwrite(pBuffer, 1, char_num, (FILE*)pFile) == char_num ? pFile : 0); + #else + return (__fwrite(pBuffer, 1, char_num, (FILE*)pFile) == char_num ? pFile : 0); + #endif } static void* __StringWrite(void* pCtrl, const char* pBuffer, size_t char_num) { @@ -1185,7 +1501,11 @@ int printf(const char* format, ...) { { va_list args; va_start(args, format); + #if PLATFORM_GCN res = __pformatter(&__FileWrite, (void*)stdout, format, args); + #else + res = __pformatter(&__FileWrite, (void*)stdout, format, args, 0); + #endif } __end_critical_region(stdin_access); return res; @@ -1202,7 +1522,11 @@ int fprintf(FILE* file, const char* format, ...) { { va_list args; va_start(args, format); + #if PLATFORM_GCN res = __pformatter(&__FileWrite, (void*)file, format, args); + #else + res = __pformatter(&__FileWrite, (void*)file, format, args, 0); + #endif } __end_critical_region(stdin_access); return res; @@ -1216,7 +1540,11 @@ int vprintf(const char* format, va_list arg) { } __begin_critical_region(stdin_access); + #if PLATFORM_GCN ret = __pformatter(&__FileWrite, (void*)stdout, format, arg); + #else + ret = __pformatter(&__FileWrite, (void*)stdout, format, arg, 0); + #endif __end_critical_region(stdin_access); return ret; } @@ -1228,15 +1556,33 @@ int vsnprintf(char* s, size_t n, const char* format, va_list arg) { osc.MaxCharCount = n; osc.CharsWritten = 0; + #if PLATFORM_GCN end = __pformatter(&__StringWrite, &osc, format, arg); + #else + end = __pformatter(&__StringWrite, &osc, format, arg, 0); + #endif if (s) { + #if PLATFORM_GCN s[(end < n) ? end : n - 1] = '\0'; + #else + if (end < n) { + s[end] = '\0'; + } else { + if (n > 0) { + s[n - 1] = '\0'; + } + } + #endif } return end; } +int vsprintf(char *s, const char *format, va_list arg) { + return vsnprintf(s, 0xFFFFFFFF, format, arg); +} + int snprintf(char* s, size_t n, const char* format, ...) { va_list args; va_start(args, format); diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/scanf.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/scanf.c index ec5fb5536a..e2016b1d41 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/scanf.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/scanf.c @@ -1,4 +1,744 @@ #include "scanf.h" +#include +#include +#include +#include +#include +#include + +enum argument_options { + normal_argument, + char_argument, + short_argument, + long_argument, + intmax_argument, + size_t_argument, + ptrdiff_argument, + long_long_argument, + double_argument, + long_double_argument, + wchar_argument +}; + +typedef unsigned char char_map[32]; + +typedef struct { + unsigned char suppress_assignment; + unsigned char field_width_specified; + unsigned char argument_options; + unsigned char conversion_char; + int field_width; + char_map char_set; +} scan_format; + +#define set_char_map(map, ch) map[(unsigned char)ch >> 3] |= (1 << (ch & 7)) +#define tst_char_map(map, ch) (map[(unsigned char)ch >> 3] & (1 << (ch & 7))) + +static const char* parse_format(const char* format_string, scan_format *format) { + const char* s = format_string; + int c; + int flag_found, invert; + scan_format f = { 0, 0, normal_argument, 0, 2147483647, { 0 } }; + + if (((c = *++s) == '%')) { + f.conversion_char = c; + *format = f; + return ((const char*)s + 1); + } + + if (c == '*') { + f.suppress_assignment = 1; + c = *++s; + } + + if (isdigit(c)) { + f.field_width = 0; + + do { + f.field_width = (f.field_width * 10) + (c - '0'); + c = *++s; + } while (isdigit(c)); + + if (f.field_width == 0) { + f.conversion_char = 0xFF; + *format = f; + return ((const char*)s + 1); + } + + f.field_width_specified = 1; + } + + flag_found = 1; + + switch (c) { + case 'h': + f.argument_options = short_argument; + + if (s[1] == 'h') { + f.argument_options = char_argument; + c = *++s; + } + + break; + case 'l': + f.argument_options = long_argument; + + if (s[1] == 'l') { + f.argument_options = long_long_argument; + c = *++s; + } + + break; + case 'L': + f.argument_options = long_double_argument; + break; + + case 'j': + f.argument_options = intmax_argument; + break; + case 'z': + f.argument_options = size_t_argument; + break; + case 't': + f.argument_options = ptrdiff_argument; + break; + default: + flag_found = 0; + } + + if (flag_found) { + c = *++s; + } + + f.conversion_char = c; + + switch (c) { + case 'd': + case 'i': + case 'u': + case 'o': + case 'x': + case 'X': + if (f.argument_options == long_double_argument) { + f.conversion_char = 0xFF; + break; + } + + break; + + case 'a': + case 'A': + case 'f': + case 'F': + case 'e': + case 'E': + case 'g': + case 'G': + if (f.argument_options == char_argument || f.argument_options == short_argument || f.argument_options == intmax_argument || f.argument_options == size_t_argument || f.argument_options == ptrdiff_argument || f.argument_options == long_long_argument) { + f.conversion_char = 0xFF; + break; + } + + if (f.argument_options == long_argument) { + f.argument_options = double_argument; + } + + break; + + case 'p': + f.argument_options = long_argument; + f.conversion_char = 'x'; + break; + + case 'c': + if (f.argument_options == long_argument) { + f.argument_options = wchar_argument; + } + else { + if (f.argument_options != normal_argument) { + f.conversion_char = 0xFF; + } + } + + break; + + case 's': + if (f.argument_options == long_argument) { + f.argument_options = wchar_argument; + } + else { + if (f.argument_options != normal_argument) { + f.conversion_char = 0xFF; + } + } + + { + int i; + unsigned char* p; + + for (i = sizeof(f.char_set), p = f.char_set; i; --i) { + *p++ = 0xFF; + } + + f.char_set[1] = 0xC1; + f.char_set[4] = 0xFE; + } + + break; + + case 'n': + break; + + case '[': + if (f.argument_options == long_argument) { + f.argument_options = wchar_argument; + } + else { + if (f.argument_options != normal_argument) { + f.conversion_char = 0xFF; + } + } + + c = *++s; + invert = 0; + + if (c == '^') { + invert = 1; + c = *++s; + } + + if (c == ']') { + set_char_map(f.char_set, ']'); + c = *++s; + } + + while (c && c != ']') { + int d; + set_char_map(f.char_set, c); + + if (*(s + 1) == '-' && (d = *(s + 2)) != 0 && d != ']') { + while (++c <= d) { + set_char_map(f.char_set, c); + } + + c = *(s += 3); + } + else { + c = *++s; + } + } + + if (!c) { + f.conversion_char = 0xFF; + break; + } + + if (invert) { + int i; + unsigned char* p; + + for (i = sizeof(f.char_set), p = f.char_set; i; --i, ++p) { + *p = ~*p; + } + + break; + } + + break; + default: + f.conversion_char = 0xFF; + break; + } + + *format = f; + return ((const char*)s + 1); +} + +static int __sformatter(int (*ReadProc)(void *, int, int), void * ReadProcArg, const char * format_str, va_list arg, int is_secure) +{ + int num_chars, chars_read, items_assigned, conversions; + int base, negative, overflow; + int rval; + const char* format_ptr; + char format_char; + char c; + scan_format format; + long long_num; + unsigned long u_long_num; + long long long_long_num = 0; + unsigned long long u_long_long_num; + long double long_double_num; + char * arg_ptr; + int elem_valid; + size_t elem_maxsize; + int match_failure = 0; + int terminate = 0; + + format_ptr = format_str; + chars_read = 0; + items_assigned = 0; + conversions = 0; + + while (!terminate && (format_char = *format_ptr) != 0) + { + if (isspace(format_char)) + { + do{ + format_char = *++format_ptr; + } while (isspace(format_char)); + + if (!match_failure) + { + while (isspace(c = (*ReadProc)(ReadProcArg, 0, __GetAChar))) + ++chars_read; + + (*ReadProc)(ReadProcArg, c, __UngetAChar); + } + continue; + } + + if ((format_char != '%') && (!match_failure)) + { + if ((c = (*ReadProc)(ReadProcArg, 0, __GetAChar)) != (unsigned char)format_char) + { + (*ReadProc)(ReadProcArg, c, __UngetAChar); + if (!is_secure) + goto exit; + else + { + match_failure = 1; + ++format_ptr; + continue; + } + } + + chars_read++; + format_ptr++; + + continue; + } + + format_ptr = parse_format(format_ptr, &format); + + if (!format.suppress_assignment && format.conversion_char != '%') + { + arg_ptr = va_arg(arg, char *); + } + else + { + arg_ptr = 0; + } + + if ((format.conversion_char != 'n') && (!match_failure) && (*ReadProc)(ReadProcArg, 0, __TestForError)) + { + if (!is_secure) + goto exit; + else + match_failure = 1; + } + + switch (format.conversion_char) + { + case 'd': + base = 10; + goto signed_int; + case 'i': + base = 0; + signed_int: + + if (match_failure) + { + long_num = 0; + long_long_num = 0; + } + else + { + if ((format.argument_options == long_long_argument) || (format.argument_options == intmax_argument)) + u_long_long_num = __strtoull(base, format.field_width, ReadProc, ReadProcArg, &num_chars, &negative, &overflow); + else + u_long_num = __strtoul(base, format.field_width, ReadProc, ReadProcArg, &num_chars, &negative, &overflow); + + if (!num_chars) + { + if (!is_secure) + goto exit; + else + { + match_failure = 1; + long_num = 0; + long_long_num = 0; + goto signed_int_assign; + } + } + + chars_read += num_chars; + + if ((format.argument_options == long_long_argument) || (format.argument_options == intmax_argument)) + long_long_num = (negative ? -u_long_long_num : u_long_long_num); + else + long_num = (negative ? -u_long_num : u_long_num); + } + + signed_int_assign: + + if (arg_ptr) + { + switch (format.argument_options) + { + case normal_argument: * (int *) arg_ptr = long_num; break; + case char_argument: * (signed char *) arg_ptr = long_num; break; + case short_argument: * (short *) arg_ptr = long_num; break; + case long_argument: * (long *) arg_ptr = long_num; break; + case intmax_argument: * (intmax_t *) arg_ptr = long_long_num; break; + case size_t_argument: * (size_t *) arg_ptr = long_num; break; + case ptrdiff_argument: * (ptrdiff_t *) arg_ptr = long_num; break; + case long_long_argument: * (long long *) arg_ptr = long_long_num; break; + } + if (!match_failure) items_assigned++; + } + + conversions++; + break; + case 'o': + base = 8; + goto unsigned_int; + case 'u': + base = 10; + goto unsigned_int; + case 'x': + case 'X': + base = 16; + unsigned_int: + + if (match_failure) + { + u_long_num = 0; + u_long_long_num = 0; + } + else + { + if ((format.argument_options == long_long_argument) || (format.argument_options == intmax_argument)) + u_long_long_num = __strtoull(base, format.field_width, ReadProc, ReadProcArg, &num_chars, &negative, &overflow); + else + u_long_num = __strtoul(base, format.field_width, ReadProc, ReadProcArg, &num_chars, &negative, &overflow); + + if (!num_chars) + { + if (!is_secure) + goto exit; + else + { + match_failure = 1; + u_long_num = 0; + u_long_long_num = 0; + goto unsigned_int_assign; + } + } + + chars_read += num_chars; + + if (negative) + if (format.argument_options == long_long_argument) + u_long_long_num = -u_long_long_num; + else + u_long_num = -u_long_num; + } + + unsigned_int_assign: + + if (arg_ptr) + { + switch (format.argument_options) + { + case normal_argument: * (unsigned int *)arg_ptr = u_long_num; break; + case char_argument: * (unsigned char *)arg_ptr = u_long_num; break; + case short_argument: * (unsigned short *)arg_ptr = u_long_num; break; + case long_argument: * (unsigned long *)arg_ptr = u_long_num; break; + case intmax_argument: * (intmax_t *) arg_ptr = u_long_long_num; break; + case size_t_argument: * (size_t *) arg_ptr = u_long_num; break; + case ptrdiff_argument: * (ptrdiff_t *) arg_ptr = u_long_num; break; + case long_long_argument: * (unsigned long long *) arg_ptr = u_long_long_num; break; + + + } + + if (!match_failure) items_assigned++; + } + + conversions++; + break; + case 'a': + case 'A': + case 'f': + case 'F': + case 'e': + case 'E': + case 'g': + case 'G': + flt: + if (match_failure) long_double_num = NAN; + else + { + long_double_num = __strtold(format.field_width, ReadProc, ReadProcArg, &num_chars, &overflow); + + if (!num_chars) + { + if (!is_secure) + goto exit; + else + { + match_failure = 1; + long_double_num = NAN; + goto assign_float; + } + } + + chars_read += num_chars; + } + + assign_float: + + if (arg_ptr) + { + switch (format.argument_options) + { + case normal_argument: * (float *) arg_ptr = long_double_num; break; + case double_argument: * (double *) arg_ptr = long_double_num; break; + case long_double_argument: * (long double *) arg_ptr = long_double_num; break; + } + + if (!match_failure) items_assigned++; + } + + conversions++; + break; + + case 'c': + + if (!format.field_width_specified) format.field_width = 1; + + if (arg_ptr) + { + if (is_secure) + { + elem_valid = 1; + elem_maxsize = va_arg(arg, size_t); + } + + num_chars = 0; + + if (match_failure) + { + if (elem_maxsize > 0) + *arg_ptr = 0; + continue; + } + else + { + char * arg_start = arg_ptr; + + while (format.field_width-- && (!is_secure || ((elem_valid = (elem_maxsize > num_chars)) != 0)) && ((rval = ((*ReadProc)(ReadProcArg, 0, __GetAChar))) != -1)) + { + c = rval; + + if (format.argument_options == wchar_argument) + { + mbtowc(((wchar_t*)arg_ptr), (char*)(&c), 1); + arg_ptr += sizeof(wchar_t); + } + else + *arg_ptr++ = c; + num_chars++; + } + + c = rval; + if (!num_chars || (is_secure && !elem_valid)) + { + if (!is_secure) + goto exit; + else + { + match_failure = 1; + if (elem_maxsize > 0) + *arg_start = 0; + continue; + } + } + + chars_read += num_chars; + + items_assigned++; + } + } + else + { + num_chars = 0; + + while (format.field_width-- && ((rval = ((*ReadProc)(ReadProcArg, 0, __GetAChar))) != -1)) + { + c = rval; + num_chars++; + } + c = rval; + if (!num_chars) goto exit; + } + + conversions++; + break; + + case '%': + if (match_failure) + continue; + else + { + while (isspace(c = (*ReadProc)(ReadProcArg, 0, __GetAChar))) + chars_read++; + + if (c != '%') + { + (*ReadProc)(ReadProcArg, c, __UngetAChar); + if (!is_secure) + goto exit; + else + { + match_failure = 1; + continue; + } + } + + chars_read++; + } + break; + + case 's': + if (!match_failure) + { + c = (*ReadProc)(ReadProcArg, 0, __GetAChar); + while(isspace(c)) + { + chars_read++; + c = (*ReadProc)(ReadProcArg, 0, __GetAChar); + } + + (*ReadProc)(ReadProcArg, c, __UngetAChar); + } + case '[': + if (arg_ptr) + { + if (is_secure) + { + elem_valid = 1; + elem_maxsize = va_arg(arg, size_t) - 1; + } + + num_chars = 0; + + if (match_failure) + { + if (elem_maxsize > 0) + *arg_ptr = 0; + continue; + } + else + { + char * arg_start = arg_ptr; + + while (format.field_width-- && + (!is_secure || ((elem_valid = (elem_maxsize >= num_chars)) != 0)) && + ((rval = ((*ReadProc)(ReadProcArg, 0, __GetAChar))) != -1)) + { + c = rval; + + if (!tst_char_map(format.char_set, c)) + break; + + if (format.argument_options == wchar_argument) + { + mbtowc(((wchar_t*)arg_ptr), (char*)&c, 1); + arg_ptr = (char*)((wchar_t*)arg_ptr + 1); + } + else + *arg_ptr++ = c; + num_chars++; + } + c = rval; + + if (!num_chars || (is_secure && !elem_valid)) + { + (*ReadProc)(ReadProcArg, c, __UngetAChar); + if (!is_secure) + goto exit; + else + { + match_failure = 1; + if (elem_maxsize > 0) + *arg_start = 0; + continue; + } + } + + chars_read += num_chars; + + if (format.argument_options == wchar_argument) + *(wchar_t*)arg_ptr = L'\0'; + else + *arg_ptr = 0; + + items_assigned++; + } + } + else + { + num_chars = 0; + + while (format.field_width-- && + ((rval = ((*ReadProc)(ReadProcArg, 0, __GetAChar))) != -1)) + { + c = rval; + if (!tst_char_map(format.char_set, c)) + break; + + num_chars++; + } + c = rval; + + if (!num_chars) + { + (*ReadProc)(ReadProcArg, c, __UngetAChar); + break; + } + chars_read += num_chars; + } + + if (format.field_width >= 0) + (*ReadProc)(ReadProcArg, c, __UngetAChar); + + conversions++; + break; + case 'n': + if (arg_ptr) + switch (format.argument_options) + { + case normal_argument: * (int *) arg_ptr = chars_read; break; + case short_argument: * (short *) arg_ptr = chars_read; break; + case long_argument: * (long *) arg_ptr = chars_read; break; + case char_argument: * (char *) arg_ptr = chars_read; break; + case long_long_argument: * (long long *) arg_ptr = chars_read; break; + } + continue; + case 0xFF: + default: + goto exit; + } + } + +exit: + + if ((*ReadProc)(ReadProcArg, 0, __TestForError) && conversions == 0) + return -1; + + return items_assigned; +} int __StringRead(void* pPtr, int ch, int act) { char ret; @@ -31,3 +771,32 @@ int __StringRead(void* pPtr, int ch, int act) { return 0; } + +int isspace_string(const char *s) { + int i = 0; + + while(s[i] != '\0'){ + if(!isspace(s[i++])) return 0; + } + + return 1; +} + +int vsscanf(const char *s, const char *format, va_list arg) { + __InStrCtrl isc; + isc.NextChar = (char*)s; + + if ((s == 0) || (*isc.NextChar == '\0') || isspace_string(s)) { + return -1; + } + + isc.NullCharDetected = 0; + return __sformatter(&__StringRead, (void*)&isc, format, arg, 0); +} + +int sscanf(const char *s, const char *pFormat, ...) { + int ret; + va_list args; + va_start(args, pFormat); + return vsscanf(s, pFormat, args); +} diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/secure_error.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/secure_error.c new file mode 100644 index 0000000000..faf85586d6 --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/secure_error.c @@ -0,0 +1,16 @@ +#include + +typedef void (*constraint_handler_t)(const char*, void*, int); + +static constraint_handler_t __msl_constraint_handler = NULL; + +void ignore_handler_s(const char* msg, void* ptr, int error); + +void __msl_runtime_constraint_violation_s(const char* msg, void* ptr, int error) { + if (__msl_constraint_handler) + (*__msl_constraint_handler)(msg, ptr, error); + else + ignore_handler_s(msg, ptr, error); +} + +void ignore_handler_s(const char* msg, void* ptr, int error) {} diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/signal.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/signal.c index bf23819570..104728a228 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/signal.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/signal.c @@ -1,14 +1,20 @@ #include "signal.h" #include "critical_regions.h" +#if PLATFORM_GCN +#define SIGNAL_NUM 6 +#else +#define SIGNAL_NUM 7 +#endif + #define __std(ref) ref -__signal_func_ptr signal_funcs[6]; +__signal_func_ptr signal_funcs[SIGNAL_NUM]; int raise(int sig) { __signal_func_ptr signal_func; - if (sig < 1 || sig > 6) { + if (sig < 1 || sig > SIGNAL_NUM) { return -1; } diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/string.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/string.c index ccfd0550c0..7c9ded40f1 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/string.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/string.c @@ -1,4 +1,5 @@ #include "cstring.h" +#include "global.h" #define K1 0x80808080 #define K2 0xFEFEFEFF @@ -42,7 +43,9 @@ char* strcpy(char* dst, const char* src) { w = *((int*)(fromb)); t = w + K2; - + #if !PLATFORM_GCN + t &= ~w; + #endif t &= K1; if (t) { goto bytecopy; @@ -54,6 +57,9 @@ char* strcpy(char* dst, const char* src) { w = *(++((int*)(fromb))); t = w + K2; + #if !PLATFORM_GCN + t &= ~w; + #endif t &= K1; if (t) { goto adjust; @@ -145,6 +151,9 @@ int strcmp(const char* str1, const char* str2) { l1 = *(int*)left; r1 = *(int*)right; x = l1 + K2; + #if !PLATFORM_GCN + x &= ~l1; + #endif if (x & K1) { goto adjust; } @@ -158,10 +167,12 @@ int strcmp(const char* str1, const char* str2) { } } +#if PLATFORM_GCN if (l1 > r1) { return 1; } return -1; +#endif adjust: l1 = *left; diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/strtold.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/strtold.c new file mode 100644 index 0000000000..b4599b1e75 --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/strtold.c @@ -0,0 +1,663 @@ +#include "strtold.h" +#include "cstdio.h" +#include "ansi_fp.h" +#include "locale.h" +#include "ctype.h" +#include "float.h" +#include "cmath.h" +#include "climits.h" +#include + +extern double nan(const char*); +extern double __dec2num(const decimal* d); + +#define TARGET_FLOAT_BITS 64 +#define TARGET_FLOAT_BYTES (TARGET_FLOAT_BITS / 8) +#define TARGET_FLOAT_MAX_EXP LDBL_MAX_EXP +#define TARGET_FLOAT_MANT_DIG LDBL_MANT_DIG +#define TARGET_FLOAT_IMPLICIT_J_BIT 1 +#define TARGET_FLOAT_MANT_BITS (TARGET_FLOAT_MANT_DIG - TARGET_FLOAT_IMPLICIT_J_BIT) +#define TARGET_FLOAT_EXP_BITS (TARGET_FLOAT_BITS - TARGET_FLOAT_MANT_BITS - 1) + +enum scan_states { + start = 0x0001, + sig_start = 0x0002, + leading_sig_zeroes = 0x0004, + int_digit_loop = 0x0008, + frac_start = 0x0010, + frac_digit_loop = 0x0020, + sig_end = 0x0040, + exp_start = 0x0080, + leading_exp_digit = 0x0100, + leading_exp_zeroes = 0x0200, + exp_digit_loop = 0x0400, + finished = 0x0800, + failure = 0x1000, + nan_state = 0x2000, + infin_state = 0x4000, + hex_state = 0x8000 +}; + +enum hex_scan_states { + not_hex = 0x0000, + hex_start = 0x0001, + hex_leading_sig_zeroes = 0x0002, + hex_int_digit_loop = 0x0004, + hex_frac_digit_loop = 0x0008, + hex_sig_end = 0x0010, + hex_exp_start = 0x0020, + hex_leading_exp_digit = 0x0040, + hex_leading_exp_zeroes = 0x0080, + hex_exp_digit_loop = 0x0100 +}; + +#define final_state(scan_state) (scan_state & (finished | failure)) +#define success(scan_state) \ + (scan_state & \ + (leading_sig_zeroes | int_digit_loop | frac_digit_loop | leading_exp_zeroes | exp_digit_loop | finished)) +#define hex_success(count, scan_state) \ + (count - 1 > 2 && scan_state & (hex_leading_sig_zeroes | hex_int_digit_loop | hex_frac_digit_loop | \ + hex_leading_exp_zeroes | hex_exp_digit_loop)) + +#define fetch() (count++, (*ReadProc)(ReadProcArg, 0, __GetAChar)) +#define unfetch(c) (*ReadProc)(ReadProcArg, c, __UngetAChar) + +long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* ReadProcArg, int* chars_scanned, + int* overflow) { + int scan_state = start; + int hex_scan_state = not_hex; + int count = 0; + int spaces = 0; + int c; + decimal d = {0, 0, 0, {0, ""}}; + int sig_negative = 0; + int exp_negative = 0; + long exp_value = 0; + int exp_adjust = 0; + register long double result = 0.0; + int sign_detected = 0; + int radix_marker = *(unsigned char*)(__lconv).decimal_point; + + unsigned char* chptr; + unsigned char mantissa[TARGET_FLOAT_BYTES]; + unsigned mantissa_digits; + unsigned long exponent = 0; + + int ui; + unsigned char uch, uch1; + int NibbleIndex; + int expsign = 0; + int exp_digits = 0; + unsigned intdigits = 0; + + *overflow = 0; + c = fetch(); + + while (count <= max_width && c != -1 && !final_state(scan_state)) { + switch (scan_state) { + case start: + if (isspace(c)) { + c = fetch(); + count--; + spaces++; + break; + } + + switch (toupper(c)) { + case '-': + sig_negative = 1; + + case '+': + c = fetch(); + sign_detected = 1; + break; + case 'I': + c = fetch(); + scan_state = infin_state; + break; + + case 'N': + c = fetch(); + scan_state = nan_state; + break; + + default: + scan_state = sig_start; + break; + } + break; + + case infin_state: { + int i = 1; + char model[] = "INFINITY"; + + while ((i < 8) && (toupper(c) == model[i])) { + i++; + c = fetch(); + } + + if ((i == 3) || (i == 8)) { + if (sig_negative) { + result = (float)-HUGE_VALF; + } else { + result = HUGE_VALF; + } + + *chars_scanned = spaces + i + sign_detected; + return result; + } else { + scan_state = failure; + } + + break; + } + + case nan_state: { + int i = 1, j = 0; + char model[] = "NAN("; + char nan_arg[32] = ""; + while ((i < 4) && (toupper(c) == model[i])) { + i++; + c = fetch(); + } + + if ((i == 3) || (i == 4)) { + if (i == 4) { + while ((j < 32) && (isdigit(c) || isalpha(c) || (c == radix_marker))) { + nan_arg[j++] = (char)c; + c = fetch(); + } + + if (c != ')') { + scan_state = failure; + break; + } else { + j++; + } + } + nan_arg[j] = '\0'; + + if (sig_negative) { + result = -nan(nan_arg); + } else { + result = nan(nan_arg); + } + + *chars_scanned = spaces + i + j + sign_detected; + return result; + } else { + scan_state = failure; + } + break; + } + + case sig_start: + if (c == radix_marker) { + scan_state = frac_start; + c = fetch(); + break; + } + if (!isdigit(c)) { + scan_state = failure; + break; + } + + if (c == '0') { + c = fetch(); + if (toupper(c) == 'X') { + scan_state = hex_state; + hex_scan_state = hex_start; + } else { + scan_state = leading_sig_zeroes; + } + break; + } + + scan_state = int_digit_loop; + break; + + case leading_sig_zeroes: + if (c == '0') { + c = fetch(); + + break; + } + scan_state = int_digit_loop; + break; + + case int_digit_loop: + if (!isdigit(c)) { + if (c == radix_marker) { + scan_state = frac_digit_loop; + c = fetch(); + } else { + scan_state = sig_end; + } + break; + } + if (d.sig.length < 20) { + d.sig.text[d.sig.length++] = (unsigned char)c; + } else { + exp_adjust++; + } + + c = fetch(); + break; + + case frac_start: + if (!isdigit(c)) { + scan_state = failure; + break; + } + + scan_state = frac_digit_loop; + break; + + case frac_digit_loop: + if (!isdigit(c)) { + scan_state = sig_end; + break; + } + + if (d.sig.length < 20) { + if (c != '0' || d.sig.length) { + d.sig.text[d.sig.length++] = (unsigned char)c; + } + + exp_adjust--; + } + c = fetch(); + break; + + case sig_end: + if (toupper(c) == 'E') { + scan_state = exp_start; + c = fetch(); + break; + } + scan_state = finished; + break; + + case exp_start: + if (c == '+') { + c = fetch(); + } else if (c == '-') { + c = fetch(); + exp_negative = 1; + } + + scan_state = leading_exp_digit; + break; + + case leading_exp_digit: + if (!isdigit(c)) { + scan_state = failure; + break; + } + + if (c == '0') { + scan_state = leading_exp_zeroes; + c = fetch(); + break; + } + + scan_state = exp_digit_loop; + break; + + case leading_exp_zeroes: + if (c == '0') { + c = fetch(); + break; + } + + scan_state = exp_digit_loop; + break; + + case exp_digit_loop: + if (!isdigit(c)) { + scan_state = finished; + break; + } + + exp_value = exp_value * 10 + (c - '0'); + if (exp_value > DBL_MAX_10_EXP) { + *overflow = 1; + } + + c = fetch(); + break; + + case hex_state: { + switch (hex_scan_state) { + case hex_start: + memset(mantissa, 0, sizeof(mantissa)); + chptr = mantissa; + mantissa_digits = (53 + 3) / 4; + intdigits = 0; + NibbleIndex = 0; + hex_scan_state = hex_leading_sig_zeroes; + c = fetch(); + break; + + case hex_leading_sig_zeroes: + if (c == '0') { + c = fetch(); + break; + } + + hex_scan_state = hex_int_digit_loop; + break; + + case hex_int_digit_loop: + if (!isxdigit(c)) { + if (c == radix_marker) { + hex_scan_state = hex_frac_digit_loop; + c = fetch(); + } + + else { + hex_scan_state = hex_sig_end; + } + break; + } + + if (intdigits < mantissa_digits) { + intdigits++; + uch = *(chptr + NibbleIndex / 2); + + ui = toupper(c); + if (ui >= 'A') { + ui = ui - 'A' + 10; + } else { + ui -= '0'; + } + + uch1 = (unsigned char)ui; + + if ((NibbleIndex % 2) != 0) { + uch |= uch1; + } else { + uch |= (unsigned char)(uch1 << 4); + } + + *(chptr + NibbleIndex++ / 2) = uch; + c = fetch(); + } + + else { + c = fetch(); + } + + break; + + case hex_frac_digit_loop: + if (!isxdigit(c)) { + hex_scan_state = hex_sig_end; + break; + } + + if (intdigits < mantissa_digits) { + uch = *(chptr + NibbleIndex / 2); + ui = toupper(c); + + if (ui >= 'A') { + ui = ui - 'A' + 10; + } else { + ui -= '0'; + } + + uch1 = (unsigned char)ui; + + if ((NibbleIndex % 2) != 0) { + uch |= uch1; + } else { + uch |= (unsigned char)(uch1 << 4); + } + + *(chptr + NibbleIndex++ / 2) = uch; + c = fetch(); + } else { + c = fetch(); + } + break; + + case hex_sig_end: + if (toupper(c) == 'P') { + hex_scan_state = hex_exp_start; + exp_digits++; + c = fetch(); + } else { + scan_state = finished; + } + + break; + + case hex_exp_start: + exp_digits++; + if (c == '-') { + expsign = 1; + } else if (c != '+') { + c = unfetch(c); + count--; + exp_digits--; + } + + hex_scan_state = hex_leading_exp_digit; + c = fetch(); + break; + + case hex_leading_exp_digit: + if (!isdigit(c)) { + scan_state = failure; + break; + } + + if (c == '0') { + exp_digits++; + hex_scan_state = hex_leading_exp_zeroes; + c = fetch(); + break; + } + + hex_scan_state = hex_exp_digit_loop; + break; + + case hex_leading_exp_zeroes: + if (c == '0') { + c = fetch(); + break; + } + + hex_scan_state = hex_exp_digit_loop; + break; + + case hex_exp_digit_loop: + if (!isdigit(c)) { + scan_state = finished; + break; + } + + exponent = exponent * 10 + (c - '0'); + + if (exp_value > SHRT_MAX) { + *overflow = 1; + } + + exp_digits++; + c = fetch(); + + break; + } + } break; + } + } + + if (scan_state != 32768 ? !success(scan_state) : !hex_success(count, hex_scan_state)) { + count = 0; + *chars_scanned = 0; + } else { + count--; + *chars_scanned = count + spaces; + } + + unfetch(c); + + if (hex_scan_state == not_hex) { + if (exp_negative) { + exp_value = -exp_value; + } + + { + int n = d.sig.length; + unsigned char* p = &d.sig.text[n]; + + while (n-- && *--p == '0') { + exp_adjust++; + } + + d.sig.length = (unsigned char)(n + 1); + + if (d.sig.length == 0) { + d.sig.text[d.sig.length++] = '0'; + } + } + + if (exp_value < DBL_MIN_10_EXP || exp_value > DBL_MAX_10_EXP) { + if (!*overflow && d.sig.text[0] == '0' && d.sig.text[1] == 0) { + return 0.0; + } + *overflow = 1; + } + + exp_value += exp_adjust; + + if (*overflow) { + if (exp_negative) { + return 0.0; + } else { + return sig_negative ? -HUGE_VAL : HUGE_VAL; + } + } + + d.exp = (short)exp_value; + + result = __dec2num(&d); + + if (result != 0.0 && result < LDBL_MIN) { + *overflow = 1; + } else if (result > LDBL_MAX) { + *overflow = 1; + result = HUGE_VAL; + } + + if (sig_negative && success(scan_state)) { + result = -result; + } + + return result; + } else { + unsigned mantissa_bit, dbl_bit; + unsigned one_bit; + long double dbl_bits_storage; + unsigned char* dbl_bits = (unsigned char*)&dbl_bits_storage; + + if (expsign) { + exponent = -exponent; + } + + exponent += intdigits * 4; + + one_bit = 0; + while (one_bit < 4 && !(mantissa[0] & (0x80 >> one_bit))) { + one_bit++; + exponent--; + } + exponent--; + + if (TARGET_FLOAT_IMPLICIT_J_BIT) { + one_bit++; + } + + if (one_bit) { + unsigned char carry = 0; + for (chptr = mantissa + sizeof(mantissa) - 1; chptr >= mantissa; chptr--) { + unsigned char a = *chptr; + *chptr = (unsigned char)((a << one_bit) | carry); + carry = (unsigned char)(a >> (8 - one_bit)); + } + } + + memset(dbl_bits, 0, sizeof(dbl_bits_storage)); + dbl_bit = (TARGET_FLOAT_BITS - TARGET_FLOAT_MANT_BITS); + + for (mantissa_bit = 0; mantissa_bit < TARGET_FLOAT_MANT_BITS; mantissa_bit += 8) { + unsigned char ui = mantissa[mantissa_bit >> 3]; + int halfbits; + + if (mantissa_bit + 8 > TARGET_FLOAT_MANT_BITS) { + ui &= 0xff << (TARGET_FLOAT_MANT_BITS - mantissa_bit); + } + + halfbits = (dbl_bit & 7); + dbl_bits[dbl_bit >> 3] |= (unsigned char)(ui >> halfbits); + dbl_bit += 8; + dbl_bits[dbl_bit >> 3] |= (unsigned char)(ui << (8 - halfbits)); + } + + exponent += (TARGET_FLOAT_MAX_EXP - 1) + exp_value; + + if ((exponent & ~(TARGET_FLOAT_MAX_EXP * 2 - 1))) { + *overflow = 1; + return 0.0; + } + + exponent <<= 32 - TARGET_FLOAT_EXP_BITS; + + dbl_bits[0] |= exponent >> 25; + + if (TARGET_FLOAT_EXP_BITS > 7) { + dbl_bits[1] |= exponent >> 17; + } + + if (TARGET_FLOAT_EXP_BITS > 15) { + dbl_bits[2] |= exponent >> 9; + } + + if (TARGET_FLOAT_EXP_BITS > 23) { + dbl_bits[3] |= exponent >> 1; + } + + if (sig_negative) { + dbl_bits[0] |= 0x80; + } + + result = *(long double*)dbl_bits; + + return result; + } +} + +double strtod(const char* str, char** end) { + double value, abs_value; + int count, overflow; + + __InStrCtrl isc; + isc.NextChar = (char *)str; + isc.NullCharDetected = 0; + + value = __strtold(INT_MAX, &__StringRead, (void *)&isc, &count, &overflow); + + if (end) + *end = (char*)str + count; + + abs_value = fabs(value); + + if (overflow) + errno = ERANGE; + + return value; +} + +double atof(const char* str) { + return strtod(str, NULL); +} diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/strtoul.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/strtoul.c index cfc907320c..3d3136e397 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/strtoul.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/strtoul.c @@ -150,6 +150,138 @@ unsigned long __strtoul(int base, int max_width, int (*ReadProc)(void*, int, int return value; } +unsigned long long __strtoull(int base, int max_width, int (*ReadProc)(void*, int, int), void* ReadProcArg, + int* chars_scanned, int* negative, int* overflow) { + int scan_state = start; + int count = 0; + int spaces = 0; + unsigned long long value = 0; + unsigned long long value_max = 0; + unsigned long long ullmax = ULLONG_MAX; + int c; + + *negative = *overflow = 0; + + if (base < 0 || base == 1 || base > 36 || max_width < 1) { + scan_state = failure; + } else { + c = fetch(); + } + + if (base != 0) { + value_max = ullmax / base; + } + + while (count <= max_width && c != -1 && !final_state(scan_state)) { + switch (scan_state) { + case start: + if (isspace(c)) { + c = fetch(); + count--; + spaces++; + break; + } + + if (c == '+') { + c = fetch(); + } else if (c == '-') { + c = fetch(); + *negative = 1; + } + + scan_state = check_for_zero; + break; + + case check_for_zero: + if (base == 0 || base == 16) { + if (c == '0') { + scan_state = leading_zero; + c = fetch(); + break; + } + } + + scan_state = need_digit; + break; + + case leading_zero: + if (c == 'X' || c == 'x') { + base = 16; + scan_state = need_digit; + c = fetch(); + break; + } + + if (base == 0) { + base = 8; + } + + scan_state = digit_loop; + break; + + case need_digit: + case digit_loop: + if (base == 0) { + base = 10; + } + + if (!value_max) { + value_max = ullmax / base; + } + + if (isdigit(c)) { + if ((c -= '0') >= base) { + if (scan_state == digit_loop) { + scan_state = finished; + } else { + scan_state = failure; + } + + c += '0'; + break; + } + } else if (!isalpha(c) || (toupper(c) - 'A' + 10) >= base) { + if (scan_state == digit_loop) { + scan_state = finished; + } else { + scan_state = failure; + } + + break; + } else { + c = toupper(c) - 'A' + 10; + } + + if (value > value_max) { + *overflow = 1; + } + + value *= base; + + if (c > (ullmax - value)) { + *overflow = 1; + } + + value += c; + scan_state = digit_loop; + c = fetch(); + break; + } + } + + if (!success(scan_state)) { + count = 0; + value = 0; + *chars_scanned = 0; + } else { + count--; + *chars_scanned = count + spaces; + } + + unfetch(c); + return value; +} + unsigned long strtoul(const char* str, char** end, int base) { unsigned long value; int count, negative, overflow; @@ -198,3 +330,7 @@ long strtol(const char* str, char** end, int base) { return svalue; } + +int atoi(const char* str) { + return strtol(str, NULL, 10); +} diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/wchar_io.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/wchar_io.c index 699e2721d8..c2f2648df1 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/wchar_io.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/wchar_io.c @@ -1,21 +1,32 @@ #include "wchar_io.h" -int fwide(FILE* file, int mode) { - if (file == NULL || file->file_mode.file_kind == __closed_file) { +int __fwide(FILE* stream, int mode) { + return fwide(stream, mode); +} + +int fwide(FILE* stream, int mode) { + int orientation; + int result; + + if (stream == NULL || stream->file_mode.file_kind == __closed_file) return 0; + + orientation = stream->file_mode.file_orientation; + switch (orientation) { + case __unoriented: + if (mode > 0) + stream->file_mode.file_orientation = __wide_oriented; + else if (mode < 0) + stream->file_mode.file_orientation = __char_oriented; + result = mode; + break; + case __wide_oriented: + result = 1; + break; + case __char_oriented: + result = -1; + break; } - switch (file->file_mode.file_orientation) { - case UNORIENTED: - if (mode > 0) { - file->file_mode.file_orientation = WIDE_ORIENTED; - } else if (mode < 0) { - file->file_mode.file_orientation = CHAR_ORIENTED; - } - return mode; - case WIDE_ORIENTED: - return 1; - case CHAR_ORIENTED: - return -1; - } + return result; } diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/wctype.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/wctype.c new file mode 100644 index 0000000000..73e8f15d71 --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/wctype.c @@ -0,0 +1,166 @@ +#include "ctype.h" + +const unsigned short __wctype_mapC[256] = { + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_blank | ctype_cntrl | ctype_space, + ctype_cntrl | ctype_space, + ctype_cntrl | ctype_space, + ctype_cntrl | ctype_space, + ctype_cntrl | ctype_space, + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_cntrl, + ctype_blank | ctype_print | ctype_space, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_digit | ctype_graph | ctype_print | ctype_xdigit, + ctype_digit | ctype_graph | ctype_print | ctype_xdigit, + ctype_digit | ctype_graph | ctype_print | ctype_xdigit, + ctype_digit | ctype_graph | ctype_print | ctype_xdigit, + ctype_digit | ctype_graph | ctype_print | ctype_xdigit, + ctype_digit | ctype_graph | ctype_print | ctype_xdigit, + ctype_digit | ctype_graph | ctype_print | ctype_xdigit, + ctype_digit | ctype_graph | ctype_print | ctype_xdigit, + ctype_digit | ctype_graph | ctype_print | ctype_xdigit, + ctype_digit | ctype_graph | ctype_print | ctype_xdigit, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_alpha | ctype_graph | ctype_print | ctype_upper | ctype_xdigit, + ctype_alpha | ctype_graph | ctype_print | ctype_upper | ctype_xdigit, + ctype_alpha | ctype_graph | ctype_print | ctype_upper | ctype_xdigit, + ctype_alpha | ctype_graph | ctype_print | ctype_upper | ctype_xdigit, + ctype_alpha | ctype_graph | ctype_print | ctype_upper | ctype_xdigit, + ctype_alpha | ctype_graph | ctype_print | ctype_upper | ctype_xdigit, + ctype_alpha | ctype_graph | ctype_print | ctype_upper, + ctype_alpha | ctype_graph | ctype_print | ctype_upper, + ctype_alpha | ctype_graph | ctype_print | ctype_upper, + ctype_alpha | ctype_graph | ctype_print | ctype_upper, + ctype_alpha | ctype_graph | ctype_print | ctype_upper, + ctype_alpha | ctype_graph | ctype_print | ctype_upper, + ctype_alpha | ctype_graph | ctype_print | ctype_upper, + ctype_alpha | ctype_graph | ctype_print | ctype_upper, + ctype_alpha | ctype_graph | ctype_print | ctype_upper, + ctype_alpha | ctype_graph | ctype_print | ctype_upper, + ctype_alpha | ctype_graph | ctype_print | ctype_upper, + ctype_alpha | ctype_graph | ctype_print | ctype_upper, + ctype_alpha | ctype_graph | ctype_print | ctype_upper, + ctype_alpha | ctype_graph | ctype_print | ctype_upper, + ctype_alpha | ctype_graph | ctype_print | ctype_upper, + ctype_alpha | ctype_graph | ctype_print | ctype_upper, + ctype_alpha | ctype_graph | ctype_print | ctype_upper, + ctype_alpha | ctype_graph | ctype_print | ctype_upper, + ctype_alpha | ctype_graph | ctype_print | ctype_upper, + ctype_alpha | ctype_graph | ctype_print | ctype_upper, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_alpha | ctype_graph | ctype_print | ctype_lower | ctype_xdigit, + ctype_alpha | ctype_graph | ctype_print | ctype_lower | ctype_xdigit, + ctype_alpha | ctype_graph | ctype_print | ctype_lower | ctype_xdigit, + ctype_alpha | ctype_graph | ctype_print | ctype_lower | ctype_xdigit, + ctype_alpha | ctype_graph | ctype_print | ctype_lower | ctype_xdigit, + ctype_alpha | ctype_graph | ctype_print | ctype_lower | ctype_xdigit, + ctype_alpha | ctype_graph | ctype_print | ctype_lower, + ctype_alpha | ctype_graph | ctype_print | ctype_lower, + ctype_alpha | ctype_graph | ctype_print | ctype_lower, + ctype_alpha | ctype_graph | ctype_print | ctype_lower, + ctype_alpha | ctype_graph | ctype_print | ctype_lower, + ctype_alpha | ctype_graph | ctype_print | ctype_lower, + ctype_alpha | ctype_graph | ctype_print | ctype_lower, + ctype_alpha | ctype_graph | ctype_print | ctype_lower, + ctype_alpha | ctype_graph | ctype_print | ctype_lower, + ctype_alpha | ctype_graph | ctype_print | ctype_lower, + ctype_alpha | ctype_graph | ctype_print | ctype_lower, + ctype_alpha | ctype_graph | ctype_print | ctype_lower, + ctype_alpha | ctype_graph | ctype_print | ctype_lower, + ctype_alpha | ctype_graph | ctype_print | ctype_lower, + ctype_alpha | ctype_graph | ctype_print | ctype_lower, + ctype_alpha | ctype_graph | ctype_print | ctype_lower, + ctype_alpha | ctype_graph | ctype_print | ctype_lower, + ctype_alpha | ctype_graph | ctype_print | ctype_lower, + ctype_alpha | ctype_graph | ctype_print | ctype_lower, + ctype_alpha | ctype_graph | ctype_print | ctype_lower, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_graph | ctype_print | ctype_punct, + ctype_cntrl, +}; + +const wchar_t __wlower_mapC[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, + 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x5B, 0x5C, 0x5D, 0x5E, + 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, + 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, + 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, + 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, + 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, + 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, + 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, + 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, +}; + +const wchar_t __wupper_mapC[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, + 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, + 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, + 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, + 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, + 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, + 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, + 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, + 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, + 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, +}; diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/wstring.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/wstring.c new file mode 100644 index 0000000000..d1647831d4 --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/wstring.c @@ -0,0 +1,44 @@ +#include "wstring.h" + +size_t wcslen(const wchar_t* str) { + size_t len = -1; + wchar_t* p = (wchar_t*)str - 1; + + do { + len++; + } while (*++p); + + return len; +} + +wchar_t* wcsncpy(wchar_t* dest, const wchar_t* src, size_t num) { + const wchar_t* p = (const wchar_t*)src - 1; + wchar_t* q = (wchar_t*)dest - 1; + wchar_t zero = 0; + + num++; + + while (--num) { + if (!(*++q = *++p)) { + while (--num) { + *++q = 0; + } + + break; + } + } + + return dest; +} + +int wcscmp(const wchar_t* str1, const wchar_t* str2) { + const wchar_t* p1 = (wchar_t*)str1 - 1; + const wchar_t* p2 = (wchar_t*)str2 - 1; + wchar_t c1, c2; + + while ((c1 = *++p1) == (c2 = *++p2)) + if (!c1) + return 0; + + return c1 - c2; +} diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c index 7e970a81d0..9588c00582 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c @@ -72,6 +72,11 @@ qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ if(hx>0) return 0.0; /* acos(1) = 0 */ else return pi+2.0*pio2_lo; /* acos(-1)= pi */ } + + #if PLATFORM_SHIELD + errno = EDOM; + #endif + return NAN; /* acos(|x|>1) is NaN */ } if(ix<0x3fe00000) { /* |x| < 0.5 */ diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c index 4058af145d..05c49cee7e 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c @@ -78,6 +78,11 @@ double __ieee754_asin(x) double x; if (((ix - 0x3ff00000) | __LO(x)) == 0) /* asin(1)=+-pi/2 with inexact */ return x * pio2_hi + x * pio2_lo; + + #if PLATFORM_SHIELD + errno = EDOM; + #endif + return NAN; /* asin(|x|>1) is NaN */ } else if (ix < 0x3fe00000) { /* |x|<0.5 */ if (ix < 0x3e400000) { /* if |x| < 2**-27 */ diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c index 2659d584bc..260085ba97 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c @@ -37,6 +37,9 @@ double __ieee754_fmod(x, y) double x, y; #endif { int n, hx, hy, hz, ix, iy, sx, i; + #if !PLATFORM_GCN + int diff; + #endif unsigned lx, ly, lz; hx = __HI(x); /* high word of x */ @@ -110,9 +113,19 @@ double __ieee754_fmod(x, y) double x, y; /* fix point fmod */ n = ix - iy; + #if !PLATFORM_GCN + diff = n + 2; + #endif + while (n--) { hz = hx - hy; lz = lx - ly; + #if PLATFORM_SHIELD + if (!hz) + if((lx >> diff) == (ly >> diff)) + return Zero[(unsigned)sx>>31]; + #endif + if (lx < ly) hz -= 1; if (hz < 0) { @@ -127,6 +140,12 @@ double __ieee754_fmod(x, y) double x, y; } hz = hx - hy; lz = lx - ly; + #if PLATFORM_SHIELD + if (!hz) + if((lx >> diff) == (ly >> diff)) + return Zero[(unsigned)sx>>31]; + #endif + if (lx < ly) hz -= 1; if (hz >= 0) { @@ -163,4 +182,4 @@ double __ieee754_fmod(x, y) double x, y; x *= one; /* create necessary signal */ } return x; /* exact output */ -} \ No newline at end of file +} diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c new file mode 100644 index 0000000000..d730d777a1 --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c @@ -0,0 +1,161 @@ +/* @(#)e_log.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_log(x) + * Return the logrithm of x + * + * Method : + * 1. Argument Reduction: find k and f such that + * x = 2^k * (1+f), + * where sqrt(2)/2 < 1+f < sqrt(2) . + * + * 2. Approximation of log(1+f). + * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) + * = 2s + 2/3 s**3 + 2/5 s**5 + ....., + * = 2s + s*R + * We use a special Reme algorithm on [0,0.1716] to generate + * a polynomial of degree 14 to approximate R The maximum error + * of this polynomial approximation is bounded by 2**-58.45. In + * other words, + * 2 4 6 8 10 12 14 + * R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s + * (the values of Lg1 to Lg7 are listed in the program) + * and + * | 2 14 | -58.45 + * | Lg1*s +...+Lg7*s - R(z) | <= 2 + * | | + * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2. + * In order to guarantee error in log below 1ulp, we compute log + * by + * log(1+f) = f - s*(f - R) (if f is not too large) + * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy) + * + * 3. Finally, log(x) = k*ln2 + log(1+f). + * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo))) + * Here ln2 is split into two floating point number: + * ln2_hi + ln2_lo, + * where n*ln2_hi is always exact for |n| < 2000. + * + * Special cases: + * log(x) is NaN with signal if x < 0 (including -INF) ; + * log(+INF) is +INF; log(0) is -INF with signal; + * log(NaN) is that NaN with no signal. + * + * Accuracy: + * according to an error analysis, the error is always less than + * 1 ulp (unit in the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif + ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ + ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ + two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */ + Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ + Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ + Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ + Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ + Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ + Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ + Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ + +static double zero = 0.0; + +#ifdef __STDC__ +double __ieee754_log(double x) +#else +double __ieee754_log(x) +double x; +#endif +{ + double hfsq, f, s, z, R, w, t1, t2, dk; + int k, hx, i, j; + unsigned lx; + + hx = __HI(x); /* high word of x */ + lx = __LO(x); /* low word of x */ + + k = 0; + if (hx < 0x00100000) { /* x < 2**-1022 */ + if (((hx & 0x7fffffff) | lx) == 0) { + return -two54 / zero; /* log(+-0)=-inf */ + } + if (hx < 0) { + errno = EDOM; + return (x - x) / zero; + } /* log(-#) = NaN */ + k -= 54; + x *= two54; /* subnormal number, scale up x */ + hx = __HI(x); /* high word of x */ + } + if (hx >= 0x7ff00000) { + return x + x; + } + k += (hx >> 20) - 1023; + hx &= 0x000fffff; + i = (hx + 0x95f64) & 0x100000; + __HI(x) = hx | (i ^ 0x3ff00000); /* normalize x or x/2 */ + k += (i >> 20); + f = x - 1.0; + if ((0x000fffff & (2 + hx)) < 3) { /* |f| < 2**-20 */ + if (f == zero) { + if (k == 0) { + return zero; + } else { + dk = (double)k; + return dk * ln2_hi + dk * ln2_lo; + } + } + R = f * f * (0.5 - 0.33333333333333333 * f); + if (k == 0) { + return f - R; + } else { + dk = (double)k; + return dk * ln2_hi - ((R - dk * ln2_lo) - f); + } + } + s = f / (2.0 + f); + dk = (double)k; + z = s * s; + i = hx - 0x6147a; + w = z * z; + j = 0x6b851 - hx; + t1 = w * (Lg2 + w * (Lg4 + w * Lg6)); + t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7))); + i |= j; + R = t2 + t1; + if (i > 0) { + hfsq = 0.5 * f * f; + if (k == 0) { + return f - (hfsq - s * (hfsq + R)); + } else { + return dk * ln2_hi - ((hfsq - (s * (hfsq + R) + dk * ln2_lo)) - f); + } + } else { + if (k == 0) { + return f - s * (f - R); + } else { + return dk * ln2_hi - ((s * (f - R) - dk * ln2_lo) - f); + } + } +} diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log10.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log10.c new file mode 100644 index 0000000000..94cdaf2061 --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log10.c @@ -0,0 +1,99 @@ + +/* @(#)e_log10.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_log10(x) + * Return the base 10 logarithm of x + * + * Method : + * Let log10_2hi = leading 40 bits of log10(2) and + * log10_2lo = log10(2) - log10_2hi, + * ivln10 = 1/log(10) rounded. + * Then + * n = ilogb(x), + * if(n<0) n = n+1; + * x = scalbn(x,-n); + * log10(x) := n*log10_2hi + (n*log10_2lo + ivln10*log(x)) + * + * Note 1: + * To guarantee log10(10**n)=n, where 10**n is normal, the rounding + * mode must set to Round-to-Nearest. + * Note 2: + * [1/log(10)] rounded to 53 bits has error .198 ulps; + * log10 is monotonic at all binary break points. + * + * Special cases: + * log10(x) is NaN with signal if x < 0; + * log10(+INF) is +INF with no signal; log10(0) is -INF with signal; + * log10(NaN) is that NaN with no signal; + * log10(10**N) = N for N=0,1,...,22. + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif + two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ + ivln10 = 4.34294481903251816668e-01, /* 0x3FDBCB7B, 0x1526E50E */ + log10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */ + log10_2lo = 3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */ + +static double zero = 0.0; + +#ifdef __STDC__ +double __ieee754_log10(double x) +#else +double __ieee754_log10(x) +double x; +#endif +{ + double y, z; + int i, k, hx; + unsigned lx; + + hx = __HI(x); /* high word of x */ + lx = __LO(x); /* low word of x */ + + k = 0; + if (hx < 0x00100000) { /* x < 2**-1022 */ + if (((hx & 0x7fffffff) | lx) == 0) { + errno = EDOM; + return -two54 / zero; + } /* log(+-0)=-inf */ + if (hx < 0) { + errno = EDOM; + return (x - x) / zero; + } /* log(-#) = NaN */ + k -= 54; + x *= two54; /* subnormal number, scale up x */ + hx = __HI(x); /* high word of x */ + } + if (hx >= 0x7ff00000) { + return x + x; + } + k += (hx >> 20) - 1023; + i = ((unsigned)k & 0x80000000) >> 31; + hx = (hx & 0x000fffff) | ((0x3ff - i) << 20); + y = (double)(k + i); + __HI(x) = hx; + z = y * log10_2lo + ivln10 * __ieee754_log(x); + return z + y * log10_2hi; +} diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c index 59b8ffe201..0fe4053e3d 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c @@ -1,59 +1,4 @@ -//======================================================================== -// -// e_pow.c -// -// Part of the standard mathematical function library -// -//======================================================================== -//####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with eCos; if not, write to the Free Software Foundation, Inc., -// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -// -// As a special exception, if other files instantiate templates or use macros -// or inline functions from this file, or you compile this file and link it -// with other works to produce a work based on this file, this file does not -// by itself cause the resulting work to be covered by the GNU General Public -// License. However the source code for this file must still be made available -// in accordance with section (3) of the GNU General Public License. -// -// This exception does not invalidate any other reasons why a work based on -// this file might be covered by the GNU General Public License. -// -// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. -// at http://sources.redhat.com/ecos/ecos-license/ -// ------------------------------------------- -//####ECOSGPLCOPYRIGHTEND#### -//======================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): jlarmour -// Contributors: -// Date: 2001-07-20 -// Purpose: -// Description: -// Usage: -// -//####DESCRIPTIONEND#### -// -//======================================================================== - -// CONFIGURATION - -/* @(#)e_pow.c 5.1 93/09/24 */ +/* @(#)e_pow.c 1.2 95/01/04 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. @@ -110,298 +55,322 @@ * to produce the hexadecimal values shown. */ -#include "types.h" #include "errno.h" #include "cmath.h" -#ifndef _DOUBLE_IS_32BITS - #ifdef __STDC__ static const double #else static double #endif -bp[] = {1.0, 1.5,}, -dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */ -dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */ -zero = 0.0, -one = 1.0, -two = 2.0, -two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */ -huge = 1.0e300, -tiny = 1.0e-300, - /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ -L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */ -L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */ -L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */ -L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */ -L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */ -L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */ -P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ -P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ -P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ -P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ -P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */ -lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */ -lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */ -lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */ -ovt = 8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */ -cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */ -cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */ -cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/ -ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */ -ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/ -ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ + bp[] = + { + 1.0, + 1.5, +}, + dp_h[] = + { + 0.0, + 5.84962487220764160156e-01, +}, /* 0x3FE2B803, 0x40000000 */ + dp_l[] = + { + 0.0, + 1.35003920212974897128e-08, +}, /* 0x3E4CFDEB, 0x43CFD006 */ + zero = 0.0, one = 1.0, two = 2.0, two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */ + big = 1.0e300, tiny = 1.0e-300, + /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ + L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */ + L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */ + L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */ + L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */ + L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */ + L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */ + P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ + P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ + P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ + P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ + P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */ + lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */ + lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */ + lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */ + ovt = 8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */ + cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */ + cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */ + cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/ + ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */ + ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/ + ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ #ifdef __STDC__ double __ieee754_pow(double x, double y) #else -double __ieee754_pow(x, y) double x, y; +double __ieee754_pow(x, y) +double x, y; #endif { - double z, ax, z_h, z_l, p_h, p_l; - double y1, t1, t2, r, s, t, u, v, w; - double qqq; // necessary temp - int i0, i1, i, j, k, yisint, n; - int hx, hy, ix, iy; - u32 lx, ly; + double z, ax, z_h, z_l, p_h, p_l; + double y1, t1, t2, r, s, t, u, v, w; + int i, j, k, yisint, n; + int hx, hy, ix, iy; + unsigned lx, ly; - i0 = ((*(int*)&one) >> 29) ^ 1; - i1 = 1 - i0; - hx = __HI(x); - lx = __LO(x); - hy = __HI(y); - ly = __LO(y); - ix = hx & 0x7fffffff; - iy = hy & 0x7fffffff; + hx = __HI(x); + lx = __LO(x); + hy = __HI(y); + ly = __LO(y); + ix = hx & 0x7fffffff; + iy = hy & 0x7fffffff; - /* y==zero: x**0 = 1 */ - if ((iy | ly) == 0) - return one; + /* y==zero: x**0 = 1 */ + if ((iy | ly) == 0) { + return one; + } - /* +-NaN return x+y */ - if (ix > 0x7ff00000 || ((ix == 0x7ff00000) && (lx != 0)) || iy > 0x7ff00000 || ((iy == 0x7ff00000) && (ly != 0))) - return x + y; + /* +-NaN return x+y */ + if (ix > 0x7ff00000 || ((ix == 0x7ff00000) && (lx != 0)) || iy > 0x7ff00000 || ((iy == 0x7ff00000) && (ly != 0))) { + return x + y; +#ifdef __STDC__ + errno = EDOM; /* mf-- added to conform to old ANSI standard */ +#endif + } - /* determine if y is an odd int when x < 0 - * yisint = 0 ... y is not an integer - * yisint = 1 ... y is an odd int - * yisint = 2 ... y is an even int - */ - yisint = 0; - if (hx < 0) { - if (iy >= 0x43400000) - yisint = 2; /* even integer y */ - else if (iy >= 0x3ff00000) { - k = (iy >> 20) - 0x3ff; /* exponent */ - if (k > 20) { - j = ly >> (52 - k); - if ((j << (52 - k)) == ly) - yisint = 2 - (j & 1); - } else if (ly == 0) { - j = iy >> (20 - k); - if ((j << (20 - k)) == iy) - yisint = 2 - (j & 1); - } - } - } + /* determine if y is an odd int when x < 0 + * yisint = 0 ... y is not an integer + * yisint = 1 ... y is an odd int + * yisint = 2 ... y is an even int + */ + yisint = 0; + if (hx < 0) { + if (iy >= 0x43400000) { + yisint = 2; /* even integer y */ + } else if (iy >= 0x3ff00000) { + k = (iy >> 20) - 0x3ff; /* exponent */ + if (k > 20) { + j = ly >> (52 - k); + if ((j << (52 - k)) == ly) { + yisint = 2 - (j & 1); + } + } else if (ly == 0) { + j = iy >> (20 - k); + if ((j << (20 - k)) == iy) { + yisint = 2 - (j & 1); + } + } + } + } - /* special value of y */ - if (ly == 0) { - if (iy == 0x7ff00000) { /* y is +-inf */ - if (((ix - 0x3ff00000) | lx) == 0) - return y - y; /* inf**+-1 is NaN */ - else if (ix >= 0x3ff00000) /* (|x|>1)**+-inf = inf,0 */ - return (hy >= 0) ? y : zero; - else /* (|x|<1)**-,+inf = inf,0 */ - return (hy < 0) ? -y : zero; - } - if (iy == 0x3ff00000) { /* y is +-1 */ - if (hy < 0) - return one / x; - else - return x; - } - if (hy == 0x40000000) - return x * x; /* y is 2 */ - if (hy == 0x3fe00000) { /* y is 0.5 */ - if (hx >= 0) /* x >= +0 */ - return sqrt(x); - } - } + /* special value of y */ + if (ly == 0) { + if (iy == 0x7ff00000) { - ax = __fabs(x); - qqq = ax; /*x is +-0,+-inf,+-1*/ - /* special value of x */ - if (lx == 0) { - if (ix == 0x7ff00000 || ix == 0 || ix == 0x3ff00000) { - z = qqq; /*x is +-0,+-inf,+-1*/ - if (hy < 0) - z = one / z; /* z = (1/|x|) */ - if (hx < 0) { - if (((ix - 0x3ff00000) | yisint) == 0) { - z = (z - z) / (z - z); /* (-1)**non-int is NaN */ - } else if (yisint == 1) - z = -z; /* (x<0)**odd = -(|x|**odd) */ - } - return z; - } - } + /* y is +-inf */ + if (((ix - 0x3ff00000) | lx) == 0) { + return y - y; /* inf**+-1 is NaN */ + } else if (ix >= 0x3ff00000) { /* (|x|>1)**+-inf = inf,0 */ + return (hy >= 0) ? y : zero; + } else { /* (|x|<1)**-,+inf = inf,0 */ + return (hy < 0) ? -y : zero; + } + } + if (iy == 0x3ff00000) { + /* y is +-1 */ + if (hy < 0) { + return one / x; + } else { + return x; + } + } + if (hy == 0x40000000) { + return x * x; /* y is 2 */ + } + if (hy == 0x3fe00000) { /* y is 0.5 */ + if (hx >= 0) { /* x >= +0 */ + return sqrt(x); + } + } + } - /* (x<0)**(non-int) is NaN */ - /* CYGNUS LOCAL: This used to be - if((((hx>>31)+1)|yisint)==0) return (x-x)/(x-x); - but ANSI C says a right shift of a signed negative quantity is - implementation defined. */ + ax = fabs(x); + /* special value of x */ + if (lx == 0) { + if (ix == 0x7ff00000 || ix == 0 || ix == 0x3ff00000) { + z = ax; /*x is +-0,+-inf,+-1*/ + if (hy < 0) { + z = one / z; /* z = (1/|x|) */ + } + if (hx < 0) { + if (((ix - 0x3ff00000) | yisint) == 0) { + z = (z - z) / (z - z); /* (-1)**non-int is NaN */ + } else if (yisint == 1) { + z = -z; /* (x<0)**odd = -(|x|**odd) */ + } + } + return z; + } + } - if (((((int)hx >> 31) + 1) | yisint) == 0) { - errno = 33; - return (double)NAN; - }; + /* (x<0)**(non-int) is NaN */ + if ((((hx >> 31) + 1) | yisint) == 0) { +#ifdef __STDC__ + errno = EDOM; /* mf-- added to conform to old ANSI standard */ +#endif + return NAN; + } - /* |y| is huge */ - if (iy > 0x41e00000) { /* if |y| > 2**31 */ - if (iy > 0x43f00000) { /* if |y| > 2**64, must o/uflow */ - if (ix <= 0x3fefffff) - return (hy < 0) ? huge * huge : tiny * tiny; - if (ix >= 0x3ff00000) - return (hy > 0) ? huge * huge : tiny * tiny; - } - /* over/underflow if x is not close to one */ - if (ix < 0x3fefffff) - return (hy < 0) ? huge * huge : tiny * tiny; - if (ix > 0x3ff00000) - return (hy > 0) ? huge * huge : tiny * tiny; - /* now |1-x| is tiny <= 2**-20, suffice to compute - log(x) by x-x^2/2+x^3/3-x^4/4 */ - t = x - 1; /* t has 20 trailing zeros */ - w = (t * t) * (0.5 - t * (0.3333333333333333333333 - t * 0.25)); - u = ivln2_h * t; /* ivln2_h has 21 sig. bits */ - v = t * ivln2_l - w * ivln2; - t1 = u + v; - __LO(t1) = 0; - t2 = v - (t1 - u); - } else { - double s2, s_h, s_l, t_h, t_l; - n = 0; - /* take care subnormal number */ - if (ix < 0x00100000) { - ax *= two53; - n -= 53; - ix = __HI(ax); - } - n += ((ix) >> 20) - 0x3ff; - j = ix & 0x000fffff; - /* determine interval */ - ix = j | 0x3ff00000; /* normalize ix */ - if (j <= 0x3988E) - k = 0; /* |x| 0x41e00000) { /* if |y| > 2**31 */ + if (iy > 0x43f00000) { /* if |y| > 2**64, must o/uflow */ + if (ix <= 0x3fefffff) { + return (hy < 0) ? big * big : tiny * tiny; + } + if (ix >= 0x3ff00000) { + return (hy > 0) ? big * big : tiny * tiny; + } + } + /* over/underflow if x is not close to one */ + if (ix < 0x3fefffff) { + return (hy < 0) ? big * big : tiny * tiny; + } + if (ix > 0x3ff00000) { + return (hy > 0) ? big * big : tiny * tiny; + } + /* now |1-x| is tiny <= 2**-20, suffice to compute + log(x) by x-x^2/2+x^3/3-x^4/4 */ + t = x - 1; /* t has 20 trailing zeros */ + w = (t * t) * (0.5 - t * (0.3333333333333333333333 - t * 0.25)); + u = ivln2_h * t; /* ivln2_h has 21 sig. bits */ + v = t * ivln2_l - w * ivln2; + t1 = u + v; + __LO(t1) = 0; + t2 = v - (t1 - u); + } else { + double s2, s_h, s_l, t_h, t_l; + n = 0; + /* take care subnormal number */ + if (ix < 0x00100000) { + ax *= two53; + n -= 53; + ix = __HI(ax); + } + n += ((ix) >> 20) - 0x3ff; + j = ix & 0x000fffff; + /* determine interval */ + ix = j | 0x3ff00000; /* normalize ix */ + if (j <= 0x3988E) { + k = 0; /* |x|> 1) | 0x20000000) + 0x00080000 + (k << 18); - t_l = ax - (t_h - bp[k]); - s_l = v * ((u - s_h * t_h) - s_h * t_l); - /* compute log(ax) */ - s2 = s * s; - r = s2 * s2 * (L1 + s2 * (L2 + s2 * (L3 + s2 * (L4 + s2 * (L5 + s2 * L6))))); - r += s_l * (s_h + s); - s2 = s_h * s_h; - t_h = 3.0 + s2 + r; - __LO(t_h) = 0; - t_l = r - ((t_h - 3.0) - s2); - /* u+v = s*(1+...) */ - u = s_h * t_h; - v = s_l * t_h + t_l * s; - /* 2/(3log2)*(s+...) */ - p_h = u + v; - __LO(p_h) = 0; - p_l = v - (p_h - u); - z_h = cp_h * p_h; /* cp_h+cp_l = 2/(3*log2) */ - z_l = cp_l * p_h + p_l * cp + dp_l[k]; - /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */ - t = (double)n; - t1 = (((z_h + z_l) + dp_h[k]) + t); - __LO(t1) = 0; - t2 = z_l - (((t1 - t) - dp_h[k]) - z_h); - } + /* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */ + u = ax - bp[k]; /* bp[0]=1.0, bp[1]=1.5 */ + v = one / (ax + bp[k]); + s = u * v; + s_h = s; + __LO(s_h) = 0; + /* t_h=ax+bp[k] High */ + t_h = zero; + __HI(t_h) = ((ix >> 1) | 0x20000000) + 0x00080000 + (k << 18); + t_l = ax - (t_h - bp[k]); + s_l = v * ((u - s_h * t_h) - s_h * t_l); + /* compute log(ax) */ + s2 = s * s; + r = s2 * s2 * (L1 + s2 * (L2 + s2 * (L3 + s2 * (L4 + s2 * (L5 + s2 * L6))))); + r += s_l * (s_h + s); + s2 = s_h * s_h; + t_h = 3.0 + s2 + r; + __LO(t_h) = 0; + t_l = r - ((t_h - 3.0) - s2); + /* u+v = s*(1+...) */ + u = s_h * t_h; + v = s_l * t_h + t_l * s; + /* 2/(3log2)*(s+...) */ + p_h = u + v; + __LO(p_h) = 0; + p_l = v - (p_h - u); + z_h = cp_h * p_h; /* cp_h+cp_l = 2/(3*log2) */ + z_l = cp_l * p_h + p_l * cp + dp_l[k]; + /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */ + t = (double)n; + t1 = (((z_h + z_l) + dp_h[k]) + t); + __LO(t1) = 0; + t2 = z_l - (((t1 - t) - dp_h[k]) - z_h); + } - s = one; /* s (sign of result -ve**odd) = -1 else = 1 */ - if (((((int)hx >> 31) + 1) | (yisint - 1)) == 0) - s = -one; /* (-ve)**(odd int) */ + s = one; /* s (sign of result -ve**odd) = -1 else = 1 */ + if ((((hx >> 31) + 1) | (yisint - 1)) == 0) { + s = -one; /* (-ve)**(odd int) */ + } - /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ - y1 = y; - __LO(y1) = 0; - p_l = (y - y1) * t1 + y * t2; - p_h = y1 * t1; - z = p_l + p_h; - j = __HI(z); - i = __LO(z); - if (j >= 0x40900000) { /* z >= 1024 */ - if (((j - 0x40900000) | i) != 0) /* if z > 1024 */ - return s * huge * huge; /* overflow */ - else { - if (p_l + ovt > z - p_h) - return s * huge * huge; /* overflow */ - } - } else if ((j & 0x7fffffff) >= 0x4090cc00) { /* z <= -1075 */ - if (((j - 0xc090cc00) | i) != 0) /* z < -1075 */ - return s * tiny * tiny; /* underflow */ - else { - if (p_l <= z - p_h) - return s * tiny * tiny; /* underflow */ - } - } - /* - * compute 2**(p_h+p_l) - */ - i = j & 0x7fffffff; - k = (i >> 20) - 0x3ff; - n = 0; - if (i > 0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */ - n = j + (0x00100000 >> (k + 1)); - k = ((n & 0x7fffffff) >> 20) - 0x3ff; /* new k for n */ - t = zero; - __HI(t) = (n & ~(0x000fffff >> k)); - n = ((n & 0x000fffff) | 0x00100000) >> (20 - k); - if (j < 0) - n = -n; - p_h -= t; - } - t = p_l + p_h; - __LO(t) = 0; - u = t * lg2_h; - v = (p_l - (t - p_h)) * lg2 + t * lg2_l; - z = u + v; - w = v - (z - u); - t = z * z; - t1 = z - t * (P1 + t * (P2 + t * (P3 + t * (P4 + t * P5)))); - r = (z * t1) / (t1 - two) - (w + z * w); - z = one - (r - z); - j = __HI(z); - j += (n << 20); - if ((j >> 20) <= 0) - z = ldexp(z, n); /* subnormal output */ - else - __HI(z) += (n << 20); - return s * z; + /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ + y1 = y; + __LO(y1) = 0; + p_l = (y - y1) * t1 + y * t2; + p_h = y1 * t1; + z = p_l + p_h; + j = __HI(z); + i = __LO(z); + if (j >= 0x40900000) { /* z >= 1024 */ + if (((j - 0x40900000) | i) != 0) { /* if z > 1024 */ + return s * big * big; /* overflow */ + } else { + if (p_l + ovt > z - p_h) { + return s * big * big; /* overflow */ + } + } + } else if ((j & 0x7fffffff) >= 0x4090cc00) { /* z <= -1075 */ + if (((j - 0xc090cc00) | i) != 0) { /* z < -1075 */ + return s * tiny * tiny; /* underflow */ + } else { + if (p_l <= z - p_h) { + return s * tiny * tiny; /* underflow */ + } + } + } + /* + * compute 2**(p_h+p_l) + */ + i = j & 0x7fffffff; + k = (i >> 20) - 0x3ff; + n = 0; + if (i > 0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */ + n = j + (0x00100000 >> (k + 1)); + k = ((n & 0x7fffffff) >> 20) - 0x3ff; /* new k for n */ + t = zero; + __HI(t) = (n & ~(0x000fffff >> k)); + n = ((n & 0x000fffff) | 0x00100000) >> (20 - k); + if (j < 0) { + n = -n; + } + p_h -= t; + } + t = p_l + p_h; + __LO(t) = 0; + u = t * lg2_h; + v = (p_l - (t - p_h)) * lg2 + t * lg2_l; + z = u + v; + w = v - (z - u); + t = z * z; + t1 = z - t * (P1 + t * (P2 + t * (P3 + t * (P4 + t * P5)))); + r = (z * t1) / (t1 - two) - (w + z * w); + z = one - (r - z); + j = __HI(z); + j += (n << 20); + if ((j >> 20) <= 0) { + #if PLATFORM_GCN + z = ldexp(z, n); /* subnormal output */ + #else + z = scalbn(z, n); /* subnormal output */ + #endif + } else { + __HI(z) += (n << 20); + } + return s * z; } - -#endif /* defined(_DOUBLE_IS_32BITS) */ - -// EOF e_pow.c diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c index 7902352ff5..20b74f00f6 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c @@ -1,3 +1,4 @@ + /* @(#)e_rem_pio2.c 1.4 95/01/18 */ /* * ==================================================== @@ -17,7 +18,7 @@ * use __kernel_rem_pio2() */ -#include "cmath.h" +#include "fdlibm.h" /* * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi @@ -27,12 +28,12 @@ static const int two_over_pi[] = { #else static int two_over_pi[] = { #endif - 0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, 0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, - 0x246E3A, 0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, 0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, - 0x7026B4, 0x5F7E41, 0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8, 0x97FFDE, 0x05980F, 0xEF2F11, - 0x8B5A0A, 0x6D1F6D, 0x367ECF, 0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5, 0xF17B3D, 0x0739F7, - 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08, 0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3, 0x91615E, - 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880, 0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B, + 0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, 0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, + 0x246E3A, 0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, 0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, + 0x7026B4, 0x5F7E41, 0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8, 0x97FFDE, 0x05980F, 0xEF2F11, + 0x8B5A0A, 0x6D1F6D, 0x367ECF, 0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5, 0xF17B3D, 0x0739F7, + 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08, 0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3, 0x91615E, + 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880, 0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B, }; #ifdef __STDC__ @@ -40,9 +41,10 @@ static const int npio2_hw[] = { #else static int npio2_hw[] = { #endif - 0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C, 0x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, - 0x4032D97C, 0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A, 0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, - 0x4042106C, 0x4042D97C, 0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB, 0x404858EB, 0x404921FB, + 0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C, 0x4025FDBB, 0x402921FB, + 0x402C463A, 0x402F6A7A, 0x4031475C, 0x4032D97C, 0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, + 0x403AB41B, 0x403C463A, 0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, 0x4042106C, 0x4042D97C, + 0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB, 0x404858EB, 0x404921FB, }; /* @@ -60,120 +62,128 @@ static const double #else static double #endif - zero - = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ - half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ - two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ + zero = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ + half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ + two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ - pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */ + pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */ pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */ - pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */ + pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */ pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */ - pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */ + pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */ pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */ #ifdef __STDC__ int __ieee754_rem_pio2(double x, double* y) #else -int __ieee754_rem_pio2(x, y) double x, y[]; +int __ieee754_rem_pio2(x, y) +double x, y[]; #endif { - double z, w, t, r, fn; - double tx[3]; - int e0, i, j, nx, n, ix, hx; + double z, w, t, r, fn; + double tx[3]; + int e0, i, j, nx, n, ix, hx; - hx = __HI(x); /* high word of x */ - ix = hx & 0x7fffffff; - if (ix <= 0x3fe921fb) /* |x| ~<= pi/4 , no need for reduction */ - { - y[0] = x; - y[1] = 0; - return 0; - } - if (ix < 0x4002d97c) { /* |x| < 3pi/4, special case with n=+-1 */ - if (hx > 0) { - z = x - pio2_1; - if (ix != 0x3ff921fb) { /* 33+53 bit pi is good enough */ - y[0] = z - pio2_1t; - y[1] = (z - y[0]) - pio2_1t; - } else { /* near pi/2, use 33+33+53 bit pi */ - z -= pio2_2; - y[0] = z - pio2_2t; - y[1] = (z - y[0]) - pio2_2t; - } - return 1; - } else { /* negative x */ - z = x + pio2_1; - if (ix != 0x3ff921fb) { /* 33+53 bit pi is good enough */ - y[0] = z + pio2_1t; - y[1] = (z - y[0]) + pio2_1t; - } else { /* near pi/2, use 33+33+53 bit pi */ - z += pio2_2; - y[0] = z + pio2_2t; - y[1] = (z - y[0]) + pio2_2t; - } - return -1; - } - } - if (ix <= 0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */ - t = fabs(x); - n = (int)(t * invpio2 + half); - fn = (double)n; - r = t - fn * pio2_1; - w = fn * pio2_1t; /* 1st round good to 85 bit */ - if (n < 32 && ix != npio2_hw[n - 1]) { - y[0] = r - w; /* quick check no cancellation */ - } else { - j = ix >> 20; - y[0] = r - w; - i = j - (((__HI(y[0])) >> 20) & 0x7ff); - if (i > 16) { /* 2nd iteration needed, good to 118 */ - t = r; - r = t - fn * pio2_2; - w = fn * pio2_2t - ((t - r) - fn * pio2_2); - y[0] = r - w; - i = j - (((__HI(y[0])) >> 20) & 0x7ff); - if (i > 49) { /* 3rd iteration need, 151 bits acc */ - t = r; /* will cover all possible cases */ - w = fn * pio2_3; - r = t - w; - w = fn * pio2_3t - ((t - r) - w); - y[0] = r - w; - } - } - } - y[1] = (r - y[0]) - w; - if (hx < 0) { - y[0] = -y[0]; - y[1] = -y[1]; - return -n; - } else - return n; - } - /* - * all other (large) arguments - */ - if (ix >= 0x7ff00000) { /* x is inf or NaN */ - y[0] = y[1] = x - x; - return 0; - } - /* set z = scalbn(|x|,ilogb(x)-23) */ - __LO(z) = __LO(x); - e0 = (ix >> 20) - 1046; /* e0 = ilogb(z)-23; */ - __HI(z) = ix - (e0 << 20); - for (i = 0; i < 2; i++) { - tx[i] = (double)((int)(z)); - z = (z - tx[i]) * two24; - } - tx[2] = z; - nx = 3; - while (tx[nx - 1] == zero) - nx--; /* skip zero term */ - n = __kernel_rem_pio2(tx, y, e0, nx, 2, two_over_pi); - if (hx < 0) { - y[0] = -y[0]; - y[1] = -y[1]; - return -n; - } - return n; + hx = __HI(x); /* high word of x */ + ix = hx & 0x7fffffff; + if (ix <= 0x3fe921fb) /* |x| ~<= pi/4 , no need for reduction */ + { + y[0] = x; + y[1] = 0; + return 0; + } + if (ix < 0x4002d97c) { /* |x| < 3pi/4, special case with n=+-1 */ + if (hx > 0) { + z = x - pio2_1; + if (ix != 0x3ff921fb) { /* 33+53 bit pi is good enough */ + y[0] = z - pio2_1t; + y[1] = (z - y[0]) - pio2_1t; + } else { /* near pi/2, use 33+33+53 bit pi */ + z -= pio2_2; + y[0] = z - pio2_2t; + y[1] = (z - y[0]) - pio2_2t; + } + return 1; + } else { /* negative x */ + z = x + pio2_1; + if (ix != 0x3ff921fb) { /* 33+53 bit pi is good enough */ + y[0] = z + pio2_1t; + y[1] = (z - y[0]) + pio2_1t; + } else { /* near pi/2, use 33+33+53 bit pi */ + z += pio2_2; + y[0] = z + pio2_2t; + y[1] = (z - y[0]) + pio2_2t; + } + return -1; + } + } + if (ix <= 0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */ + t = __fabs(x); + n = (int)(t * invpio2 + half); + fn = (double)n; + r = t - fn * pio2_1; + w = fn * pio2_1t; /* 1st round good to 85 bit */ + if (n < 32 && ix != npio2_hw[n - 1]) { + y[0] = r - w; /* quick check no cancellation */ + } else { + j = ix >> 20; + y[0] = r - w; + i = j - (((__HI(y[0])) >> 20) & 0x7ff); + if (i > 16) { /* 2nd iteration needed, good to 118 */ + t = r; + #if PLATFORM_WII || PLATFORM_SHIELD + w = fn * pio2_2; + r = t - w; + w = fn * pio2_2t - ((t - r) - w); + #else + r = t - fn * pio2_2; + w = fn * pio2_2t - ((t - r) - fn * pio2_2); + #endif + y[0] = r - w; + i = j - (((__HI(y[0])) >> 20) & 0x7ff); + if (i > 49) { /* 3rd iteration need, 151 bits acc */ + t = r; /* will cover all possible cases */ + w = fn * pio2_3; + r = t - w; + w = fn * pio2_3t - ((t - r) - w); + y[0] = r - w; + } + } + } + y[1] = (r - y[0]) - w; + if (hx < 0) { + y[0] = -y[0]; + y[1] = -y[1]; + return -n; + } else { + return n; + } + } + /* + * all other (large) arguments + */ + if (ix >= 0x7ff00000) { /* x is inf or NaN */ + y[0] = y[1] = x - x; + return 0; + } + /* set z = scalbn(|x|,ilogb(x)-23) */ + __LO(z) = __LO(x); + e0 = (ix >> 20) - 1046; /* e0 = ilogb(z)-23; */ + __HI(z) = ix - (e0 << 20); + for (i = 0; i < 2; i++) { + tx[i] = (double)((int)(z)); + z = (z - tx[i]) * two24; + } + tx[2] = z; + nx = 3; + while (tx[nx - 1] == zero) { + nx--; /* skip zero term */ + } + n = __kernel_rem_pio2(tx, y, e0, nx, 2, two_over_pi); + if (hx < 0) { + y[0] = -y[0]; + y[1] = -y[1]; + return -n; + } + return n; } diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c index f77b012e25..c681f5cce4 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c @@ -349,4 +349,4 @@ recompute: } } return n & 7; -} \ No newline at end of file +} diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c index de906d1ef4..3fe3aea68b 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c @@ -11,7 +11,15 @@ * ==================================================== */ +#include "global.h" + +#if PLATFORM_GCN #include "cmath.h" /* for isfinite macro */ +#else +#include +#define isfinite(x) ((__fpclassifyd(x) > 2)) +#endif + static const double two54 diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log10.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log10.c new file mode 100644 index 0000000000..48b21001a9 --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log10.c @@ -0,0 +1,28 @@ +/* @(#)w_log10.c 1.2 95/01/04 */ +/* $Id: w_log10.c,v 1.3 2004/02/26 17:03:30 ceciliar Exp $ */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * wrapper log10(X) + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + double log10(double x) /* wrapper log10 */ +#else + double log10(x) /* wrapper log10 */ + double x; +#endif +{ + return __ieee754_log10(x); +} diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Include/fdlibm.h b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Include/fdlibm.h index 407419ba58..e9f774a08f 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Include/fdlibm.h +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Include/fdlibm.h @@ -1,6 +1,8 @@ #ifndef FDLIBM_H #define FDLIBM_H +#include + /* @(#)fdlibm.h 1.5 04/04/22 */ /* * ==================================================== @@ -225,4 +227,4 @@ extern int __kernel_rem_pio2 __P((double*, double*, int, int, int, const int*)); }; #endif -#endif /* FDLIBM_H */ \ No newline at end of file +#endif /* FDLIBM_H */ diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Src/ansi_fp.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Src/ansi_fp.c index 2e1e641266..879effbd02 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Src/ansi_fp.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Src/ansi_fp.c @@ -1,7 +1,7 @@ #include "ansi_fp.h" #include "ansi_fp.h" #include "climits.h" -#include "float.h" +#include "cmath.h" static int __count_trailing_zerol(unsigned long x) { int result = 0; @@ -101,6 +101,7 @@ static void __rounddec(decimal* d, int digits) { void __ull2dec(decimal* result, unsigned long long val) { result->sign = 0; + #if PLATFORM_GCN if (val == 0) { result->exp = 0; result->sig.length = 1; @@ -112,6 +113,7 @@ void __ull2dec(decimal* result, unsigned long long val) { val = -val; result->sign = 1; } + #endif result->sig.length = 0; @@ -345,6 +347,7 @@ int __equals_dec(const decimal* x, const decimal* y) { } } + #if PLATFORM_GCN if (l == x->sig.length) { for (; i < y->sig.length; ++i) { if (y->sig.text[i] != 0) { @@ -358,6 +361,17 @@ int __equals_dec(const decimal* x, const decimal* y) { } } } + #else + if (l == x->sig.length) { + x = y; + } + + for (; i < x->sig.length; ++i) { + if (x->sig.text[i] != 0) { + return 0; + } + } + #endif return 1; } @@ -563,7 +577,157 @@ void __num2dec(const decform* form, double x, decimal* d) { d->exp -= d->sig.length - 1; - for (i = 0; i < d->sig.length; i++) { + for (i = 0; i < d->sig.length; ++i) { d->sig.text[i] += '0'; } } + +#if !PLATFORM_GCN +double __dec2num(const decimal* d) { + if (d->sig.length <= 0) { + return copysign(0.0, d->sign == 0 ? 1.0 : -1.0); + } + + switch (d->sig.text[0]) { + case '0': + return copysign(0.0, d->sign == 0 ? 1.0 : -1.0); + case 'I': + return copysign((double)HUGE_VALF, d->sign == 0 ? 1.0 : -1.0); + case 'N': { + double result; + unsigned long long* ll = (unsigned long long*)&result; + + *ll = 0x7FF0000000000000; + if (d->sign) + *ll |= 0x8000000000000000; + *ll |= 0x8000000000000; + + return result; + } + } + + { + static double pow_10[8] = {1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8}; + + decimal dec = *d; + unsigned char* i = dec.sig.text; + unsigned char* e = i + dec.sig.length; + double first_guess; + int exponent; + + for (; i < e; ++i) + *i -= '0'; + dec.exp += dec.sig.length - 1; + exponent = dec.exp; + + { + decimal max; + + __str2dec(&max, "179769313486231580793728714053034151", 308); + if (__less_dec(&max, &dec)) { + return copysign((double)HUGE_VALF, d->sign == 0 ? 1.0 : -1.0); + } + } + + i = dec.sig.text; + first_guess = *i++; + + while (i < e) { + unsigned long ival = 0; + int j; + double temp1, temp2; + int ndig = (int)(e - i) % 8; + + if (ndig == 0) + ndig = 8; + + for (j = 0; j < ndig; ++j, ++i) { + ival = ival * 10 + *i; + } + + temp1 = first_guess * pow_10[ndig - 1]; + temp2 = temp1 + ival; + + if (ival != 0 && temp1 == temp2) + break; + + first_guess = temp2; + exponent -= ndig; + } + + if (exponent < 0) { + first_guess /= pow(5.0, -exponent); + } else { + first_guess *= pow(5.0, exponent); + } + + first_guess = ldexp(first_guess, exponent); + + if (fpclassify(first_guess) == 2) { + first_guess = LDBL_MAX; + } + + { + decimal feedback1, feedback2, difflow, diffhigh; + double next_guess; + unsigned long long* ull = (unsigned long long*)&next_guess; + int guessed_low = 0; + + __num2dec_internal(&feedback1, first_guess); + + if (__equals_dec(&feedback1, &dec)) { + goto done; + } + if (__less_dec(&feedback1, &dec)) { + guessed_low = 1; + } + + next_guess = first_guess; + + while (1) { + if (guessed_low) { + ++*ull; + if (fpclassify(next_guess) == 2) { + goto done; + } + } else { + --*ull; + } + + __num2dec_internal(&feedback2, next_guess); + if (guessed_low && !__less_dec(&feedback2, &dec)) { + break; + } else if (!guessed_low && !__less_dec(&dec, &feedback2)) { + difflow = feedback1; + feedback1 = feedback2; + feedback2 = difflow; + { + double temp = first_guess; + first_guess = next_guess; + next_guess = temp; + } + break; + } + feedback1 = feedback2; + first_guess = next_guess; + } + + __minus_dec(&difflow, &dec, &feedback1); + __minus_dec(&diffhigh, &feedback2, &dec); + + if (__equals_dec(&difflow, &diffhigh)) { + if (*(unsigned long long*)&first_guess & 1) { + first_guess = next_guess; + } + } else if (!__less_dec(&difflow, &diffhigh)) { + first_guess = next_guess; + } + } + done: + if (dec.sign) { + first_guess = -first_guess; + } + return first_guess; + } +} +#endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Src/math_sun.c b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Src/math_sun.c new file mode 100644 index 0000000000..aba9df81ed --- /dev/null +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Src/math_sun.c @@ -0,0 +1,13 @@ +#include + +double scalbn(double x, int n) { + double mant; + int exp; + double result; + + mant = frexp(x, &exp); + exp += n; + result = ldexp(mant, exp); + + return result; +} diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/PPC_EABI/Src/abort_exit_ppc_eabi.c b/src/PowerPC_EABI_Support/MSL/MSL_C/PPC_EABI/Src/abort_exit_ppc_eabi.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/PPC_EABI/Src/math_ppc.c b/src/PowerPC_EABI_Support/MSL/MSL_C/PPC_EABI/Src/math_ppc.c index e4d8023c9e..05f574a394 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/PPC_EABI/Src/math_ppc.c +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/PPC_EABI/Src/math_ppc.c @@ -14,6 +14,8 @@ #endif #endif +double nan(const char* arg) {} + DECL_WEAK float acosf(float x) { return acos(x); }