mirror of https://github.com/zeldaret/mm.git
libultra/libc cleanup (#1757)
* libultra/libc cleanup * Format * Correct prototype for strchr * Different prototypes for bzero, bcmp, bcopy under __GNUC__ to match builtin prototypes * Correct alloca prototype
This commit is contained in:
parent
fc8d1165c8
commit
01a1b113b4
|
@ -3,10 +3,15 @@
|
||||||
|
|
||||||
#include "stdarg.h"
|
#include "stdarg.h"
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
void bcopy(void* __src, void* __dest, int __n);
|
void bzero(void* begin, unsigned int length);
|
||||||
int bcmp(void* __s1, void* __s2, int __n);
|
int bcmp(const void* __s1, const void* __s2, unsigned int __n);
|
||||||
|
void bcopy(const void* __src, void* __dest, unsigned int __n);
|
||||||
|
#else
|
||||||
void bzero(void* begin, int length);
|
void bzero(void* begin, int length);
|
||||||
|
int bcmp(const void* __s1, const void* __s2, int __n);
|
||||||
|
void bcopy(const void* __src, void* __dest, int __n);
|
||||||
|
#endif
|
||||||
|
|
||||||
void osSyncPrintf(const char* fmt, ...);
|
void osSyncPrintf(const char* fmt, ...);
|
||||||
|
|
||||||
|
|
|
@ -1,38 +1,44 @@
|
||||||
#ifndef PR_XSTDIO_H
|
#ifndef PR_XSTDIO_H
|
||||||
#define PR_XSTDIO_H
|
#define PR_XSTDIO_H
|
||||||
|
|
||||||
#include "ultratypes.h"
|
|
||||||
#include "stdarg.h"
|
#include "stdarg.h"
|
||||||
|
|
||||||
|
// IDO doesn't support long double types, improve portability for compilers supporting them
|
||||||
|
#ifdef __sgi
|
||||||
|
#define LONG_DOUBLE_TYPE double
|
||||||
|
#else
|
||||||
|
#define LONG_DOUBLE_TYPE long double
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* 0x0 */ union {
|
/* 0x00 */ union {
|
||||||
/* 0x0 */ s64 ll;
|
long long ll;
|
||||||
/* 0x0 */ f64 ld;
|
LONG_DOUBLE_TYPE ld;
|
||||||
} v;
|
} v;
|
||||||
/* 0x8 */ char* s;
|
/* 0x08 */ char* s;
|
||||||
/* 0xC */ s32 n0;
|
/* 0x0C */ int n0;
|
||||||
/* 0x10 */ s32 nz0;
|
/* 0x10 */ int nz0;
|
||||||
/* 0x14 */ s32 n1;
|
/* 0x14 */ int n1;
|
||||||
/* 0x18 */ s32 nz1;
|
/* 0x18 */ int nz1;
|
||||||
/* 0x1C */ s32 n2;
|
/* 0x1C */ int n2;
|
||||||
/* 0x20 */ s32 nz2;
|
/* 0x20 */ int nz2;
|
||||||
/* 0x24 */ s32 prec;
|
/* 0x24 */ int prec;
|
||||||
/* 0x28 */ s32 width;
|
/* 0x28 */ int width;
|
||||||
/* 0x2C */ size_t nchar;
|
/* 0x2C */ size_t nchar;
|
||||||
/* 0x30 */ u32 flags;
|
/* 0x30 */ unsigned int flags;
|
||||||
/* 0x34 */ u8 qual;
|
/* 0x34 */ char qual;
|
||||||
} _Pft;
|
} _Pft;
|
||||||
|
|
||||||
typedef void* (*PrintCallback)(void*, const char*, size_t);
|
typedef void* (*PrintCallback)(void*, const char*, size_t);
|
||||||
|
|
||||||
#define FLAGS_SPACE 1
|
#define FLAGS_SPACE (1 << 0)
|
||||||
#define FLAGS_PLUS 2
|
#define FLAGS_PLUS (1 << 1)
|
||||||
#define FLAGS_MINUS 4
|
#define FLAGS_MINUS (1 << 2)
|
||||||
#define FLAGS_HASH 8
|
#define FLAGS_HASH (1 << 3)
|
||||||
#define FLAGS_ZERO 16
|
#define FLAGS_ZERO (1 << 4)
|
||||||
|
|
||||||
int _Printf(PrintCallback pfn, void* arg, const char* fmt, va_list ap);
|
int _Printf(PrintCallback pfn, void* arg, const char* fmt, va_list ap);
|
||||||
void _Litob(_Pft* args, u8 type);
|
void _Litob(_Pft* args, char code);
|
||||||
void _Ldtob(_Pft* args, u8 type);
|
void _Ldtob(_Pft* args, char code);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef LIBC_ALLOCA_H
|
#ifndef LIBC_ALLOCA_H
|
||||||
#define LIBC_ALLOCA_H
|
#define LIBC_ALLOCA_H
|
||||||
|
|
||||||
void* alloca(u32);
|
void* alloca(size_t);
|
||||||
#define alloca __builtin_alloca
|
#define alloca(size) __builtin_alloca(size)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
#ifndef LIBC_STDDEF_H
|
#ifndef LIBC_STDDEF_H
|
||||||
#define LIBC_STDDEF_H
|
#define LIBC_STDDEF_H
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL ((void*)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(_SIZE_T)
|
#if !defined(_SIZE_T)
|
||||||
#define _SIZE_T
|
#define _SIZE_T
|
||||||
#if defined(_MIPS_SZLONG) && (_MIPS_SZLONG == 64)
|
#if defined(_MIPS_SZLONG) && (_MIPS_SZLONG == 64)
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "stddef.h"
|
#include "stddef.h"
|
||||||
|
|
||||||
const char* strchr(const char* s, int c);
|
char* strchr(const char* s, int c);
|
||||||
size_t strlen(const char* s);
|
size_t strlen(const char* s);
|
||||||
void* memcpy(void* s1, const void* s2, size_t n);
|
void* memcpy(void* s1, const void* s2, size_t n);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#include "ultra64.h"
|
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
|
|
||||||
ldiv_t ldiv(long numer, long denom) {
|
ldiv_t ldiv(long numer, long denom) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "ultra64.h"
|
// IDO Compiler Intrinsics for 64-bit arithmetic
|
||||||
|
|
||||||
long long __ull_rshift(unsigned long long left, unsigned long long right) {
|
long long __ull_rshift(unsigned long long left, unsigned long long right) {
|
||||||
return left >> right;
|
return left >> right;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "ultra64.h"
|
// IDO Compiler Intrinsics for 64-bit conversion
|
||||||
|
|
||||||
long long __d_to_ll(double d) {
|
long long __d_to_ll(double d) {
|
||||||
return d;
|
return d;
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
#include "ultra64.h"
|
|
||||||
#include "stdlib.h"
|
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
const char* strchr(const char* s, int c) {
|
char* strchr(const char* s, int c) {
|
||||||
const unsigned char ch = c;
|
const unsigned char ch = c;
|
||||||
|
|
||||||
while (*s != ch) {
|
while (*s != ch) {
|
||||||
|
@ -12,7 +10,7 @@ const char* strchr(const char* s, int c) {
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return s;
|
return (char*)s;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t strlen(const char* s) {
|
size_t strlen(const char* s) {
|
||||||
|
@ -26,8 +24,8 @@ size_t strlen(const char* s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void* memcpy(void* s1, const void* s2, size_t n) {
|
void* memcpy(void* s1, const void* s2, size_t n) {
|
||||||
unsigned char* su1 = (unsigned char*)s1;
|
char* su1 = (char*)s1;
|
||||||
const unsigned char* su2 = (const unsigned char*)s2;
|
const char* su2 = (const char*)s2;
|
||||||
|
|
||||||
while (n > 0) {
|
while (n > 0) {
|
||||||
*su1 = *su2;
|
*su1 = *su2;
|
||||||
|
@ -36,5 +34,5 @@ void* memcpy(void* s1, const void* s2, size_t n) {
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
|
|
||||||
return s1;
|
return (void*)s1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
#include "ultra64.h"
|
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
#include "PR/xstdio.h"
|
||||||
|
|
||||||
#define BUFF_LEN 0x20
|
#define BUFF_LEN 0x20
|
||||||
|
|
||||||
s16 _Ldunscale(s16*, _Pft*);
|
short _Ldunscale(short*, _Pft*);
|
||||||
void _Genld(_Pft*, u8, u8*, s16, s16);
|
void _Genld(_Pft*, char, char*, short, short);
|
||||||
|
|
||||||
const f64 digs[] = { 10e0L, 10e1L, 10e3L, 10e7L, 10e15L, 10e31L, 10e63L, 10e127L, 10e255L };
|
static const double pows[] = { 10e0L, 10e1L, 10e3L, 10e7L, 10e15L, 10e31L, 10e63L, 10e127L, 10e255L };
|
||||||
|
|
||||||
/* float properties */
|
/* float properties */
|
||||||
#define _D0 0
|
#define _D0 0
|
||||||
|
@ -42,128 +42,125 @@ const f64 digs[] = { 10e0L, 10e1L, 10e3L, 10e7L, 10e15L, 10e31L, 10e63L, 10e127L
|
||||||
#define _D3 3
|
#define _D3 3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void _Ldtob(_Pft* args, u8 type) {
|
void _Ldtob(_Pft* args, char code) {
|
||||||
u8 buff[BUFF_LEN];
|
char buff[BUFF_LEN];
|
||||||
u8* ptr = buff;
|
char* p = buff;
|
||||||
u32 sp70;
|
LONG_DOUBLE_TYPE ldval = args->v.ld;
|
||||||
f64 val = args->v.ld;
|
short err;
|
||||||
/* maybe struct? */
|
short nsig;
|
||||||
s16 err;
|
short xexp;
|
||||||
s16 nsig;
|
|
||||||
s16 exp;
|
|
||||||
s32 i;
|
|
||||||
s32 n;
|
|
||||||
f64 factor;
|
|
||||||
s32 gen;
|
|
||||||
s32 j;
|
|
||||||
s32 lo;
|
|
||||||
ldiv_t qr;
|
|
||||||
u8 drop;
|
|
||||||
s32 n2;
|
|
||||||
|
|
||||||
if (args->prec < 0) {
|
if (args->prec < 0) {
|
||||||
args->prec = 6;
|
args->prec = 6;
|
||||||
} else if ((args->prec == 0) && ((type == 'g') || (type == 'G'))) {
|
} else if ((args->prec == 0) && ((code == 'g') || (code == 'G'))) {
|
||||||
args->prec = 1;
|
args->prec = 1;
|
||||||
}
|
}
|
||||||
err = _Ldunscale(&exp, (_Pft*)args);
|
|
||||||
|
err = _Ldunscale(&xexp, (_Pft*)args);
|
||||||
if (err > 0) {
|
if (err > 0) {
|
||||||
memcpy(args->s, err == 2 ? "NaN" : "Inf", args->n1 = 3);
|
memcpy(args->s, err == 2 ? "NaN" : "Inf", args->n1 = 3);
|
||||||
return;
|
return;
|
||||||
}
|
} else if (err == 0) {
|
||||||
if (err == 0) {
|
|
||||||
nsig = 0;
|
nsig = 0;
|
||||||
exp = 0;
|
xexp = 0;
|
||||||
} else {
|
} else {
|
||||||
if (val < 0) {
|
{
|
||||||
val = -val;
|
int i;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if (ldval < 0) {
|
||||||
|
ldval = -ldval;
|
||||||
}
|
}
|
||||||
exp = exp * 30103 / 0x000186A0 - 4;
|
xexp = xexp * 30103 / 0x000186A0 - 4;
|
||||||
if (exp < 0) {
|
if (xexp < 0) {
|
||||||
n = (3 - exp) & ~3;
|
n = (3 - xexp) & ~3;
|
||||||
exp = -n;
|
xexp = -n;
|
||||||
for (i = 0; n > 0; n >>= 1, i++) {
|
for (i = 0; n > 0; n >>= 1, i++) {
|
||||||
if ((n & 1) != 0) {
|
if ((n & 1) != 0) {
|
||||||
val *= digs[i];
|
ldval *= pows[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (exp > 0) {
|
} else if (xexp > 0) {
|
||||||
factor = 1;
|
LONG_DOUBLE_TYPE factor = 1;
|
||||||
exp &= ~3;
|
xexp &= ~3;
|
||||||
|
|
||||||
for (n = exp, i = 0; n > 0; n >>= 1, i++) {
|
for (n = xexp, i = 0; n > 0; n >>= 1, i++) {
|
||||||
if ((n & 1) != 0) {
|
if ((n & 1) != 0) {
|
||||||
factor *= digs[i];
|
factor *= pows[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val /= factor;
|
ldval /= factor;
|
||||||
}
|
}
|
||||||
gen = ((type == 'f') ? exp + 10 : 6) + args->prec;
|
}
|
||||||
|
{
|
||||||
|
int gen = ((code == 'f') ? xexp + 10 : 6) + args->prec;
|
||||||
if (gen > 0x13) {
|
if (gen > 0x13) {
|
||||||
gen = 0x13;
|
gen = 0x13;
|
||||||
}
|
}
|
||||||
*ptr++ = '0';
|
|
||||||
while ((gen > 0) && (0 < val)) {
|
for (*p++ = '0'; (gen > 0) && (0 < ldval); p += 8) {
|
||||||
lo = val;
|
int j;
|
||||||
|
long lo = ldval;
|
||||||
|
|
||||||
if ((gen -= 8) > 0) {
|
if ((gen -= 8) > 0) {
|
||||||
val = (val - lo) * 1.0e8;
|
ldval = (ldval - lo) * 1.0e8;
|
||||||
}
|
}
|
||||||
ptr = ptr + 8;
|
|
||||||
|
p += 8;
|
||||||
for (j = 8; (lo > 0) && (--j >= 0);) {
|
for (j = 8; (lo > 0) && (--j >= 0);) {
|
||||||
|
ldiv_t qr;
|
||||||
qr = ldiv(lo, 10);
|
qr = ldiv(lo, 10);
|
||||||
*--ptr = qr.rem + '0';
|
*--p = qr.rem + '0';
|
||||||
lo = qr.quot;
|
lo = qr.quot;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (--j >= 0) {
|
while (--j >= 0) {
|
||||||
ptr--;
|
*--p = '0';
|
||||||
*ptr = '0';
|
|
||||||
}
|
}
|
||||||
ptr += 8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gen = ptr - &buff[1];
|
gen = p - &buff[1];
|
||||||
for (ptr = &buff[1], exp += 7; *ptr == '0'; ptr++) {
|
for (p = &buff[1], xexp += 7; *p == '0'; p++) {
|
||||||
--gen, --exp;
|
--gen, --xexp;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsig = ((type == 'f') ? exp + 1 : (((type == 'e') || (type == 'E')) ? 1 : 0)) + args->prec;
|
nsig = args->prec + ((code == 'f') ? (xexp + 1) : (((code == 'e') || (code == 'E')) ? 1 : 0));
|
||||||
if (gen < nsig) {
|
if (gen < nsig) {
|
||||||
nsig = gen;
|
nsig = gen;
|
||||||
}
|
}
|
||||||
if (nsig > 0) {
|
|
||||||
if ((nsig < gen) && (ptr[nsig] > '4')) {
|
|
||||||
drop = '9';
|
|
||||||
} else {
|
|
||||||
drop = '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
for (n2 = nsig; ptr[--n2] == drop;) {
|
if (nsig > 0) {
|
||||||
|
const char drop = ((nsig < gen) && (p[nsig] > '4')) ? '9' : '0';
|
||||||
|
int n;
|
||||||
|
|
||||||
|
for (n = nsig; p[--n] == drop;) {
|
||||||
nsig--;
|
nsig--;
|
||||||
}
|
}
|
||||||
if (drop == '9') {
|
if (drop == '9') {
|
||||||
ptr[n2]++;
|
p[n]++;
|
||||||
}
|
}
|
||||||
if (n2 < 0) {
|
if (n < 0) {
|
||||||
--ptr, ++nsig, ++exp;
|
--p, ++nsig, ++xexp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_Genld((_Pft*)args, type, ptr, nsig, exp);
|
}
|
||||||
|
_Genld((_Pft*)args, code, p, nsig, xexp);
|
||||||
}
|
}
|
||||||
|
|
||||||
s16 _Ldunscale(s16* pex, _Pft* px) {
|
short _Ldunscale(short* pex, _Pft* px) {
|
||||||
u16* ps = (u16*)px;
|
unsigned short* ps = (unsigned short*)px;
|
||||||
s16 xchar = (ps[_D0] & _DMASK) >> _DOFF;
|
short xchar = (ps[_D0] & _DMASK) >> _DOFF;
|
||||||
|
|
||||||
if (xchar == _DMAX) { /* NaN or INF */
|
if (xchar == _DMAX) { /* NaN or INF */
|
||||||
*pex = 0;
|
*pex = 0;
|
||||||
return (s16)(ps[_D0] & _DFRAC || ps[_D1] || ps[_D2] || ps[_D3] ? NAN : INF);
|
return ps[_D0] & _DFRAC || ps[_D1] || ps[_D2] || ps[_D3] ? NAN : INF;
|
||||||
} else if (0 < xchar) {
|
} else if (0 < xchar) {
|
||||||
ps[_D0] = (ps[_D0] & ~_DMASK) | (_DBIAS << _DOFF);
|
ps[_D0] = (ps[_D0] & ~_DMASK) | (_DBIAS << _DOFF);
|
||||||
*pex = xchar - (_DBIAS - 1);
|
*pex = xchar - (_DBIAS - 1);
|
||||||
return FINITE;
|
return FINITE;
|
||||||
}
|
}
|
||||||
if (0 > xchar) {
|
if (xchar < 0) {
|
||||||
return NAN;
|
return NAN;
|
||||||
} else {
|
} else {
|
||||||
*pex = 0;
|
*pex = 0;
|
||||||
|
@ -171,17 +168,16 @@ s16 _Ldunscale(s16* pex, _Pft* px) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _Genld(_Pft* px, u8 code, u8* p, s16 nsig, s16 xexp) {
|
void _Genld(_Pft* px, char code, char* p, short nsig, short xexp) {
|
||||||
u8 point = '.';
|
const char point = '.';
|
||||||
|
|
||||||
if (nsig <= 0) {
|
if (nsig <= 0) {
|
||||||
nsig = 1,
|
nsig = 1, p = "0";
|
||||||
|
|
||||||
p = (u8*)"0";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((code == 'f') || (((code == 'g') || (code == 'G')) && (-4 <= xexp) && (xexp < px->prec))) { /* 'f' format */
|
if ((code == 'f') || (((code == 'g') || (code == 'G')) && (-4 <= xexp) && (xexp < px->prec))) { /* 'f' format */
|
||||||
++xexp; /* change to leading digit count */
|
xexp++; /* change to leading digit count */
|
||||||
|
|
||||||
if (code != 'f') { /* fixup for 'g' */
|
if (code != 'f') { /* fixup for 'g' */
|
||||||
if (!(px->flags & FLAGS_HASH) && nsig < px->prec) {
|
if (!(px->flags & FLAGS_HASH) && nsig < px->prec) {
|
||||||
px->prec = nsig;
|
px->prec = nsig;
|
||||||
|
@ -190,9 +186,10 @@ void _Genld(_Pft* px, u8 code, u8* p, s16 nsig, s16 xexp) {
|
||||||
px->prec = 0;
|
px->prec = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xexp <= 0) { /* digits only to right of point */
|
if (xexp <= 0) { /* digits only to right of point */
|
||||||
px->s[px->n1++] = '0';
|
px->s[px->n1++] = '0';
|
||||||
if (0 < px->prec || px->flags & FLAGS_HASH) {
|
if ((px->prec > 0) || (px->flags & FLAGS_HASH)) {
|
||||||
px->s[px->n1++] = point;
|
px->s[px->n1++] = point;
|
||||||
}
|
}
|
||||||
if (px->prec < -xexp) {
|
if (px->prec < -xexp) {
|
||||||
|
@ -209,7 +206,7 @@ void _Genld(_Pft* px, u8 code, u8* p, s16 nsig, s16 xexp) {
|
||||||
memcpy(&px->s[px->n1], p, nsig);
|
memcpy(&px->s[px->n1], p, nsig);
|
||||||
px->n1 += nsig;
|
px->n1 += nsig;
|
||||||
px->nz1 = xexp - nsig;
|
px->nz1 = xexp - nsig;
|
||||||
if (0 < px->prec || px->flags & FLAGS_HASH) {
|
if ((px->prec > 0) || (px->flags & FLAGS_HASH)) {
|
||||||
px->s[px->n1] = point, ++px->n2;
|
px->s[px->n1] = point, ++px->n2;
|
||||||
}
|
}
|
||||||
px->nz2 = px->prec;
|
px->nz2 = px->prec;
|
||||||
|
@ -217,7 +214,7 @@ void _Genld(_Pft* px, u8 code, u8* p, s16 nsig, s16 xexp) {
|
||||||
memcpy(&px->s[px->n1], p, xexp);
|
memcpy(&px->s[px->n1], p, xexp);
|
||||||
px->n1 += xexp;
|
px->n1 += xexp;
|
||||||
nsig -= xexp;
|
nsig -= xexp;
|
||||||
if (0 < px->prec || px->flags & FLAGS_HASH) {
|
if ((px->prec > 0) || (px->flags & FLAGS_HASH)) {
|
||||||
px->s[px->n1++] = point;
|
px->s[px->n1++] = point;
|
||||||
}
|
}
|
||||||
if (px->prec < nsig) {
|
if (px->prec < nsig) {
|
||||||
|
@ -235,13 +232,13 @@ void _Genld(_Pft* px, u8 code, u8* p, s16 nsig, s16 xexp) {
|
||||||
if (--px->prec < 0) {
|
if (--px->prec < 0) {
|
||||||
px->prec = 0;
|
px->prec = 0;
|
||||||
}
|
}
|
||||||
code = code == 'g' ? 'e' : 'E';
|
code = (code == 'g') ? 'e' : 'E';
|
||||||
}
|
}
|
||||||
px->s[px->n1++] = *p++;
|
px->s[px->n1++] = *p++;
|
||||||
if (0 < px->prec || px->flags & FLAGS_HASH) {
|
if ((px->prec > 0) || (px->flags & FLAGS_HASH)) {
|
||||||
px->s[px->n1++] = point;
|
px->s[px->n1++] = point;
|
||||||
}
|
}
|
||||||
if (0 < px->prec) { /* put fraction digits */
|
if (px->prec > 0) { /* put fraction digits */
|
||||||
if (px->prec < --nsig) {
|
if (px->prec < --nsig) {
|
||||||
nsig = px->prec;
|
nsig = px->prec;
|
||||||
}
|
}
|
||||||
|
@ -249,26 +246,27 @@ void _Genld(_Pft* px, u8 code, u8* p, s16 nsig, s16 xexp) {
|
||||||
px->n1 += nsig;
|
px->n1 += nsig;
|
||||||
px->nz1 = px->prec - nsig;
|
px->nz1 = px->prec - nsig;
|
||||||
}
|
}
|
||||||
p = (u8*)&px->s[px->n1]; /* put exponent */
|
p = &px->s[px->n1]; /* put exponent */
|
||||||
*p++ = code;
|
*p++ = code;
|
||||||
if (0 <= xexp) {
|
if (xexp >= 0) {
|
||||||
*p++ = '+';
|
*p++ = '+';
|
||||||
} else { /* negative exponent */
|
} else { /* negative exponent */
|
||||||
*p++ = '-';
|
*p++ = '-';
|
||||||
xexp = -xexp;
|
xexp = -xexp;
|
||||||
}
|
}
|
||||||
if (100 <= xexp) { /* put oversize exponent */
|
if (xexp >= 100) { /* put oversize exponent */
|
||||||
if (1000 <= xexp) {
|
if (xexp >= 1000) {
|
||||||
*p++ = xexp / 1000 + '0', xexp %= 1000;
|
*p++ = xexp / 1000 + '0', xexp %= 1000;
|
||||||
}
|
}
|
||||||
*p++ = xexp / 100 + '0', xexp %= 100;
|
*p++ = xexp / 100 + '0', xexp %= 100;
|
||||||
}
|
}
|
||||||
*p++ = xexp / 10 + '0', xexp %= 10;
|
*p++ = xexp / 10 + '0', xexp %= 10;
|
||||||
|
|
||||||
*p++ = xexp + '0';
|
*p++ = xexp + '0';
|
||||||
px->n2 = p - (u8*)&px->s[px->n1];
|
px->n2 = p - &px->s[px->n1];
|
||||||
}
|
}
|
||||||
if ((px->flags & (FLAGS_ZERO | FLAGS_MINUS)) == FLAGS_ZERO) { /* pad with leading zeros */
|
if ((px->flags & (FLAGS_ZERO | FLAGS_MINUS)) == FLAGS_ZERO) { /* pad with leading zeros */
|
||||||
s32 n = px->n0 + px->n1 + px->nz1 + px->n2 + px->nz2;
|
int n = px->n0 + px->n1 + px->nz1 + px->n2 + px->nz2;
|
||||||
|
|
||||||
if (n < px->width) {
|
if (n < px->width) {
|
||||||
px->nz0 = px->width - n;
|
px->nz0 = px->width - n;
|
||||||
|
|
|
@ -1,58 +1,54 @@
|
||||||
#include "ultra64.h"
|
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
#include "PR/xstdio.h"
|
||||||
|
|
||||||
#define BUFF_LEN 0x18
|
#define BUFF_LEN 0x18
|
||||||
|
|
||||||
char ldigs[] = "0123456789abcdef";
|
char ldigs[] = "0123456789abcdef";
|
||||||
char udigs[] = "0123456789ABCDEF";
|
char udigs[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
void _Litob(_Pft* args, u8 type) {
|
void _Litob(_Pft* args, char code) {
|
||||||
u8 buff[BUFF_LEN];
|
char buff[BUFF_LEN];
|
||||||
const char* numMap;
|
const char* digs;
|
||||||
s32 base;
|
int base;
|
||||||
s32 idx;
|
int i;
|
||||||
u64 num;
|
unsigned long long ullval;
|
||||||
lldiv_t quotrem;
|
|
||||||
|
|
||||||
if (type == 'X') {
|
digs = (code == 'X') ? udigs : ldigs;
|
||||||
numMap = udigs;
|
|
||||||
} else {
|
base = (code == 'o') ? 8 : (((code != 'x') && (code != 'X')) ? 10 : 16);
|
||||||
numMap = ldigs;
|
i = BUFF_LEN;
|
||||||
|
ullval = args->v.ll;
|
||||||
|
|
||||||
|
if (((code == 'd') || (code == 'i')) && (args->v.ll < 0)) {
|
||||||
|
ullval = -ullval;
|
||||||
}
|
}
|
||||||
|
|
||||||
base = (type == 'o') ? 8 : (((type != 'x') && (type != 'X')) ? 10 : 16);
|
if ((ullval != 0) || (args->prec != 0)) {
|
||||||
idx = BUFF_LEN;
|
buff[--i] = digs[ullval % base];
|
||||||
num = args->v.ll;
|
|
||||||
|
|
||||||
if (((type == 'd') || (type == 'i')) && (args->v.ll < 0)) {
|
|
||||||
num = -num;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((num != 0) || (args->prec != 0)) {
|
args->v.ll = ullval / base;
|
||||||
buff[--idx] = numMap[num % base];
|
|
||||||
|
while ((args->v.ll > 0) && (i > 0)) {
|
||||||
|
lldiv_t qr;
|
||||||
|
qr = lldiv(args->v.ll, base);
|
||||||
|
args->v.ll = qr.quot;
|
||||||
|
buff[--i] = digs[qr.rem];
|
||||||
}
|
}
|
||||||
|
|
||||||
args->v.ll = num / base;
|
args->n1 = BUFF_LEN - i;
|
||||||
|
|
||||||
while ((args->v.ll > 0) && (idx > 0)) {
|
memcpy(args->s, buff + i, args->n1);
|
||||||
quotrem = lldiv(args->v.ll, base);
|
|
||||||
args->v.ll = quotrem.quot;
|
|
||||||
buff[--idx] = numMap[quotrem.rem];
|
|
||||||
}
|
|
||||||
|
|
||||||
args->n1 = BUFF_LEN - idx;
|
|
||||||
|
|
||||||
memcpy(args->s, buff + idx, args->n1);
|
|
||||||
|
|
||||||
if (args->n1 < args->prec) {
|
if (args->n1 < args->prec) {
|
||||||
args->nz0 = args->prec - args->n1;
|
args->nz0 = args->prec - args->n1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((args->prec < 0) && ((args->flags & (FLAGS_ZERO | FLAGS_MINUS)) == FLAGS_ZERO)) {
|
if ((args->prec < 0) && ((args->flags & (FLAGS_ZERO | FLAGS_MINUS)) == FLAGS_ZERO)) {
|
||||||
idx = args->width - args->n0 - args->nz0 - args->n1;
|
i = args->width - args->n0 - args->nz0 - args->n1;
|
||||||
if (idx > 0) {
|
if (i > 0) {
|
||||||
args->nz0 += idx;
|
args->nz0 += i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,20 @@
|
||||||
#include "ultra64.h"
|
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "stdint.h"
|
||||||
|
#include "PR/xstdio.h"
|
||||||
|
|
||||||
|
#define LDSIGN(x) (((unsigned short*)&(x))[0] & 0x8000)
|
||||||
|
|
||||||
|
char spaces[] = " ";
|
||||||
|
char zeroes[] = "00000000000000000000000000000000";
|
||||||
|
#define MAX_PAD ((sizeof(spaces) - 1))
|
||||||
|
|
||||||
#define ATOI(i, a) \
|
#define ATOI(i, a) \
|
||||||
for (i = 0; (*a >= '0') && (*a <= '9'); a++) \
|
for (i = 0; (*a >= '0') && (*a <= '9'); a++) \
|
||||||
if (i < 999) \
|
if (i < 999) \
|
||||||
i = *a + i * 10 - '0';
|
i = *a + i * 10 - '0';
|
||||||
|
|
||||||
#define _PROUT(fmt, _size) \
|
#define PUT(fmt, _size) \
|
||||||
if (_size > 0) { \
|
if (_size > 0) { \
|
||||||
arg = (void*)pfn(arg, fmt, _size); \
|
arg = (void*)pfn(arg, fmt, _size); \
|
||||||
if (arg != NULL) \
|
if (arg != NULL) \
|
||||||
|
@ -15,52 +23,52 @@
|
||||||
return x.nchar; \
|
return x.nchar; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _PAD(m, src, extracond) \
|
#define PAD(m, src, extracond) \
|
||||||
if (extracond && (m > 0)) { \
|
if ((extracond) && (m > 0)) { \
|
||||||
int i; \
|
int i; \
|
||||||
int j; \
|
int j; \
|
||||||
for (j = m; j > 0; j -= i) { \
|
for (j = m; j > 0; j -= i) { \
|
||||||
if ((u32)j > 32) \
|
if ((unsigned int)j > MAX_PAD) \
|
||||||
i = 32; \
|
i = (int)MAX_PAD; \
|
||||||
else \
|
else \
|
||||||
i = j; \
|
i = j; \
|
||||||
_PROUT(src, i); \
|
PUT(src, i); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
char spaces[] = " ";
|
void _Putfld(_Pft* px, va_list* pap, char code, char* ac);
|
||||||
char zeroes[] = "00000000000000000000000000000000";
|
|
||||||
|
|
||||||
void _Putfld(_Pft* px, va_list* pap, unsigned char code, unsigned char* ac);
|
|
||||||
|
|
||||||
int _Printf(PrintCallback pfn, void* arg, const char* fmt, va_list ap) {
|
int _Printf(PrintCallback pfn, void* arg, const char* fmt, va_list ap) {
|
||||||
_Pft x;
|
_Pft x;
|
||||||
x.nchar = 0;
|
x.nchar = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
const char* s;
|
const char* s;
|
||||||
u8 c;
|
char c;
|
||||||
const char* t;
|
const char* t;
|
||||||
|
|
||||||
static const char fchar[] = " +-#0";
|
static const char fchar[] = " +-#0";
|
||||||
static const u32 fbit[] = { FLAGS_SPACE, FLAGS_PLUS, FLAGS_MINUS, FLAGS_HASH, FLAGS_ZERO, 0 };
|
static const int fbit[] = { FLAGS_SPACE, FLAGS_PLUS, FLAGS_MINUS, FLAGS_HASH, FLAGS_ZERO, 0 };
|
||||||
|
|
||||||
unsigned char ac[0x20];
|
char ac[0x20];
|
||||||
|
|
||||||
s = fmt;
|
s = fmt;
|
||||||
while (((c = *s) != 0) && (c != '%')) {
|
for (c = *s; c != 0 && c != '%';) {
|
||||||
s++;
|
c = *++s;
|
||||||
}
|
}
|
||||||
_PROUT((char*)fmt, s - fmt);
|
|
||||||
|
PUT((char*)fmt, s - fmt);
|
||||||
|
|
||||||
if (c == 0) {
|
if (c == 0) {
|
||||||
return x.nchar;
|
return x.nchar;
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt = ++s;
|
fmt = ++s;
|
||||||
x.flags = 0;
|
for (x.flags = 0; (t = strchr(fchar, *s)) != NULL; s++) {
|
||||||
for (; (t = strchr(fchar, *s)) != NULL; s++) {
|
|
||||||
x.flags |= fbit[t - fchar];
|
x.flags |= fbit[t - fchar];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*s == '*') {
|
if (*s == '*') {
|
||||||
x.width = va_arg(ap, s32);
|
x.width = va_arg(ap, int);
|
||||||
if (x.width < 0) {
|
if (x.width < 0) {
|
||||||
x.width = -x.width;
|
x.width = -x.width;
|
||||||
x.flags |= FLAGS_MINUS;
|
x.flags |= FLAGS_MINUS;
|
||||||
|
@ -69,61 +77,59 @@ int _Printf(PrintCallback pfn, void* arg, const char* fmt, va_list ap) {
|
||||||
} else {
|
} else {
|
||||||
ATOI(x.width, s);
|
ATOI(x.width, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*s != '.') {
|
if (*s != '.') {
|
||||||
x.prec = -1;
|
x.prec = -1;
|
||||||
} else {
|
} else if (*++s == '*') {
|
||||||
s++;
|
x.prec = va_arg(ap, int);
|
||||||
if (*s == '*') {
|
|
||||||
x.prec = va_arg(ap, s32);
|
|
||||||
s++;
|
s++;
|
||||||
} else {
|
} else {
|
||||||
ATOI(x.prec, s);
|
ATOI(x.prec, s);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (strchr("hlL", *s) != NULL) {
|
|
||||||
x.qual = *s++;
|
|
||||||
} else {
|
|
||||||
x.qual = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
x.qual = (strchr("hlL", *s) != NULL) ? *s++ : '\0';
|
||||||
if ((x.qual == 'l') && (*s == 'l')) {
|
if ((x.qual == 'l') && (*s == 'l')) {
|
||||||
x.qual = 'L';
|
x.qual = 'L';
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
|
|
||||||
_Putfld(&x, &ap, *s, ac);
|
_Putfld(&x, &ap, *s, ac);
|
||||||
|
|
||||||
x.width -= x.n0 + x.nz0 + x.n1 + x.nz1 + x.n2 + x.nz2;
|
x.width -= x.n0 + x.nz0 + x.n1 + x.nz1 + x.n2 + x.nz2;
|
||||||
_PAD(x.width, spaces, !(x.flags & FLAGS_MINUS));
|
|
||||||
_PROUT((char*)ac, x.n0);
|
PAD(x.width, spaces, !(x.flags & FLAGS_MINUS));
|
||||||
_PAD(x.nz0, zeroes, 1);
|
PUT((char*)ac, x.n0);
|
||||||
_PROUT(x.s, x.n1);
|
PAD(x.nz0, zeroes, 1);
|
||||||
_PAD(x.nz1, zeroes, 1);
|
PUT(x.s, x.n1);
|
||||||
_PROUT((char*)(&x.s[x.n1]), x.n2)
|
PAD(x.nz1, zeroes, 1);
|
||||||
_PAD(x.nz2, zeroes, 1);
|
PUT((char*)(&x.s[x.n1]), x.n2)
|
||||||
_PAD(x.width, spaces, x.flags & FLAGS_MINUS);
|
PAD(x.nz2, zeroes, 1);
|
||||||
|
PAD(x.width, spaces, x.flags & FLAGS_MINUS);
|
||||||
|
|
||||||
fmt = (char*)s + 1;
|
fmt = (char*)s + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _Putfld(_Pft* px, va_list* pap, unsigned char code, unsigned char* ac) {
|
void _Putfld(_Pft* px, va_list* pap, char code, char* ac) {
|
||||||
px->n0 = px->nz0 = px->n1 = px->nz1 = px->n2 = px->nz2 = 0;
|
px->n0 = px->nz0 = px->n1 = px->nz1 = px->n2 = px->nz2 = 0;
|
||||||
|
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case 'c':
|
case 'c':
|
||||||
ac[px->n0++] = va_arg(*pap, u32);
|
ac[px->n0++] = va_arg(*pap, unsigned int);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'i':
|
case 'i':
|
||||||
if (px->qual == 'l') {
|
if (px->qual == 'l') {
|
||||||
px->v.ll = va_arg(*pap, s32);
|
px->v.ll = va_arg(*pap, long);
|
||||||
} else if (px->qual == 'L') {
|
} else if (px->qual == 'L') {
|
||||||
px->v.ll = va_arg(*pap, s64);
|
px->v.ll = va_arg(*pap, long long);
|
||||||
} else {
|
} else {
|
||||||
px->v.ll = va_arg(*pap, s32);
|
px->v.ll = va_arg(*pap, int);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (px->qual == 'h') {
|
if (px->qual == 'h') {
|
||||||
px->v.ll = (s16)px->v.ll;
|
px->v.ll = (short)px->v.ll;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (px->v.ll < 0) {
|
if (px->v.ll < 0) {
|
||||||
|
@ -144,17 +150,17 @@ void _Putfld(_Pft* px, va_list* pap, unsigned char code, unsigned char* ac) {
|
||||||
case 'u':
|
case 'u':
|
||||||
case 'o':
|
case 'o':
|
||||||
if (px->qual == 'l') {
|
if (px->qual == 'l') {
|
||||||
px->v.ll = va_arg(*pap, s32);
|
px->v.ll = va_arg(*pap, long);
|
||||||
} else if (px->qual == 'L') {
|
} else if (px->qual == 'L') {
|
||||||
px->v.ll = va_arg(*pap, s64);
|
px->v.ll = va_arg(*pap, long long);
|
||||||
} else {
|
} else {
|
||||||
px->v.ll = va_arg(*pap, s32);
|
px->v.ll = va_arg(*pap, int);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (px->qual == 'h') {
|
if (px->qual == 'h') {
|
||||||
px->v.ll = (u16)px->v.ll;
|
px->v.ll = (unsigned short)px->v.ll;
|
||||||
} else if (px->qual == 0) {
|
} else if (px->qual == 0) {
|
||||||
px->v.ll = (u32)px->v.ll;
|
px->v.ll = (unsigned int)px->v.ll;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (px->flags & FLAGS_HASH) {
|
if (px->flags & FLAGS_HASH) {
|
||||||
|
@ -173,9 +179,9 @@ void _Putfld(_Pft* px, va_list* pap, unsigned char code, unsigned char* ac) {
|
||||||
case 'g':
|
case 'g':
|
||||||
case 'E':
|
case 'E':
|
||||||
case 'G':
|
case 'G':
|
||||||
px->v.ld = (px->qual == 'L') ? va_arg(*pap, f64) : va_arg(*pap, f64);
|
px->v.ld = (px->qual == 'L') ? va_arg(*pap, LONG_DOUBLE_TYPE) : va_arg(*pap, double);
|
||||||
|
|
||||||
if (*(u16*)&px->v.ll & 0x8000) {
|
if (LDSIGN(px->v.ll)) {
|
||||||
ac[px->n0++] = '-';
|
ac[px->n0++] = '-';
|
||||||
} else if (px->flags & FLAGS_PLUS) {
|
} else if (px->flags & FLAGS_PLUS) {
|
||||||
ac[px->n0++] = '+';
|
ac[px->n0++] = '+';
|
||||||
|
@ -189,19 +195,19 @@ void _Putfld(_Pft* px, va_list* pap, unsigned char code, unsigned char* ac) {
|
||||||
|
|
||||||
case 'n':
|
case 'n':
|
||||||
if (px->qual == 'h') {
|
if (px->qual == 'h') {
|
||||||
*(va_arg(*pap, u16*)) = px->nchar;
|
*(va_arg(*pap, unsigned short*)) = px->nchar;
|
||||||
} else if (px->qual == 'l') {
|
} else if (px->qual == 'l') {
|
||||||
*va_arg(*pap, u32*) = px->nchar;
|
*va_arg(*pap, unsigned long*) = px->nchar;
|
||||||
} else if (px->qual == 'L') {
|
} else if (px->qual == 'L') {
|
||||||
*va_arg(*pap, u64*) = px->nchar;
|
*va_arg(*pap, unsigned long long*) = px->nchar;
|
||||||
} else {
|
} else {
|
||||||
*va_arg(*pap, u32*) = px->nchar;
|
*va_arg(*pap, unsigned int*) = px->nchar;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
px->v.ll = (long)va_arg(*pap, void*);
|
px->v.ll = (intptr_t)va_arg(*pap, void*);
|
||||||
px->s = (char*)&ac[px->n0];
|
px->s = &ac[px->n0];
|
||||||
_Litob(px, 'x');
|
_Litob(px, 'x');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue