mirror of
https://github.com/zeldaret/tp
synced 2026-05-23 06:54:28 -04:00
msl_c mostly matching for wii/shield (#2994)
This commit is contained in:
@@ -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:
|
||||
|
||||
+5
-2
@@ -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 = [
|
||||
|
||||
+2
-5
@@ -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
|
||||
|
||||
@@ -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--;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
#endif
|
||||
|
||||
@@ -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 <locale.h>
|
||||
|
||||
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 */
|
||||
#endif /* _MSL_COMMON_CTYPE_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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define _MSL_COMMON_FLOAT_H
|
||||
|
||||
#include <fdlibm.h>
|
||||
#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 */
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
#ifndef _MSL_LOCALE_H
|
||||
#define _MSL_LOCALE_H
|
||||
|
||||
#include <cstddef.h>
|
||||
|
||||
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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef _MSL_WCTYPE_H
|
||||
#define _MSL_WCTYPE_H
|
||||
|
||||
#include <cstddef.h>
|
||||
|
||||
#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 */
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef MSL_WSTRING_H
|
||||
#define MSL_WSTRING_H
|
||||
|
||||
#include <cstddef.h>
|
||||
|
||||
#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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#include "critical_regions.h"
|
||||
#include <cstring.h>
|
||||
|
||||
#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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
#include <locale.h>
|
||||
#include <ctype.h>
|
||||
#include <wctype_api.h>
|
||||
#include <mbstring.h>
|
||||
|
||||
#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
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#include "global.h"
|
||||
|
||||
// necessary to generate symbols in this TU
|
||||
#undef MSL_INLINE
|
||||
#define MSL_INLINE __declspec(weak)
|
||||
|
||||
#include <cmath.h>
|
||||
@@ -1,64 +1,103 @@
|
||||
#include "mbstring.h"
|
||||
#include "cstring.h"
|
||||
#include <locale.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,4 +1,744 @@
|
||||
#include "scanf.h"
|
||||
#include <ctype.h>
|
||||
#include <cmath.h>
|
||||
#include <cstdio.h>
|
||||
#include <cstdint.h>
|
||||
#include <strtoul.h>
|
||||
#include <strtold.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#include <cstdio.h>
|
||||
|
||||
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) {}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 <errno.h>
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
+20
-1
@@ -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 */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+99
@@ -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;
|
||||
}
|
||||
+293
-324
@@ -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|<sqrt(3/2) */
|
||||
else if (j < 0xBB67A)
|
||||
k = 1; /* |x|<sqrt(3) */
|
||||
else {
|
||||
k = 0;
|
||||
n += 1;
|
||||
ix -= 0x00100000;
|
||||
}
|
||||
__HI(ax) = ix;
|
||||
/* |y| is big */
|
||||
if (iy > 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|<sqrt(3/2) */
|
||||
} else if (j < 0xBB67A) {
|
||||
k = 1; /* |x|<sqrt(3) */
|
||||
} else {
|
||||
k = 0;
|
||||
n += 1;
|
||||
ix -= 0x00100000;
|
||||
}
|
||||
__HI(ax) = ix;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
/* 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
|
||||
|
||||
+125
-115
@@ -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;
|
||||
}
|
||||
|
||||
+1
-1
@@ -349,4 +349,4 @@ recompute:
|
||||
}
|
||||
}
|
||||
return n & 7;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,15 @@
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#include "global.h"
|
||||
|
||||
#if PLATFORM_GCN
|
||||
#include "cmath.h" /* for isfinite macro */
|
||||
#else
|
||||
#include <fdlibm.h>
|
||||
#define isfinite(x) ((__fpclassifyd(x) > 2))
|
||||
#endif
|
||||
|
||||
static const double
|
||||
|
||||
two54
|
||||
|
||||
+28
@@ -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);
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef FDLIBM_H
|
||||
#define FDLIBM_H
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
/* @(#)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 */
|
||||
#endif /* FDLIBM_H */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#include <cmath.h>
|
||||
|
||||
double scalbn(double x, int n) {
|
||||
double mant;
|
||||
int exp;
|
||||
double result;
|
||||
|
||||
mant = frexp(x, &exp);
|
||||
exp += n;
|
||||
result = ldexp(mant, exp);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -14,6 +14,8 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
double nan(const char* arg) {}
|
||||
|
||||
DECL_WEAK float acosf(float x) {
|
||||
return acos(x);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user