Skip to content

[do-not-upstream] GNU toolchain Picolibc fixes (arc-2025.09) #24

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: arc-2025.09
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions newlib/libc/tinystdio/conv_flt.c
Original file line number Diff line number Diff line change
Expand Up @@ -431,8 +431,12 @@ conv_flt (FLT_STREAM *stream, FLT_CONTEXT *context, width_t width, void *addr, u
if (!isdigit (edig))
{
scanf_ungetc(edig, stream, context);
if (esign != EOF)
scanf_ungetc(esign, stream, context);
if (esign != EOF) {
esign = scanf_getc (stream, context);
if(!isdigit (esign))
return 0;
scanf_ungetc(edig, stream, context);
}
goto no_exp;
}

Expand Down
3 changes: 3 additions & 0 deletions newlib/libc/tinystdio/stdio.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ typedef __uint16_t __ungetc_t;
struct __file {
__ungetc_t unget; /* ungetc() buffer */
__uint8_t flags; /* flags, see below */
#ifdef __IO_PERCENT_N
size_t buflimit; /* buffer limit size */
#endif
#define __SRD 0x0001 /* OK to read */
#define __SWR 0x0002 /* OK to write */
#define __SERR 0x0004 /* found error */
Expand Down
8 changes: 8 additions & 0 deletions newlib/libc/tinystdio/stdio_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@
#include <stdio-bufio.h>
#include <sys/lock.h>

#ifdef __IO_PERCENT_N
#define PRINTF_BUF_LIMIT(_s, _end) \
.buflimit = (size_t)((_end) ? ((char *)(_end) - (char *)(_s)) : (INT_MAX)),
#else
#define PRINTF_BUF_LIMIT(_s, _end)
#endif

struct __file_str {
struct __file file; /* main file struct */
char *pos; /* current buffer position */
Expand Down Expand Up @@ -111,6 +118,7 @@ bool __matchcaseprefix(const char *input, const char *pattern);
#define FDEV_SETUP_STRING_WRITE(_s, _end) { \
.file = { \
.flags = __SWR, \
PRINTF_BUF_LIMIT(_s, _end) \
.put = __file_str_put, \
__LOCK_INIT_NONE \
}, \
Expand Down
39 changes: 29 additions & 10 deletions newlib/libc/tinystdio/vfprintf.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,15 @@ typedef long ultoa_signed_t;
#define arg_to_unsigned(ap, flags, result_var) arg_to_t(ap, flags, unsigned, result_var)
#define arg_to_signed(ap, flags, result_var) arg_to_t(ap, flags, signed, result_var)

#define ASSIGN_STREAM_LEN(stream_len, buflimit, flags, type) \
if (flags & __SBUF) { \
*va_arg(ap, type *) = stream_len; \
} else { \
*va_arg(ap, type *) = ((size_t)stream_len >= buflimit) ? \
(type)buflimit : \
(type)stream_len; \
}

#include "ultoa_invert.c"

/* Order is relevant here and matches order in format string */
Expand Down Expand Up @@ -1192,17 +1201,25 @@ int vfprintf (FILE * stream, const CHAR *fmt, va_list ap_orig)
goto handle_error;
#else
if (flags & FL_LONG) {
if (flags & FL_REPD_TYPE)
*va_arg(ap, long long *) = stream_len;
else
*va_arg(ap, long *) = stream_len;
if ((flags)&FL_REPD_TYPE) {
ASSIGN_STREAM_LEN(stream_len, stream->buflimit,
stream->flags, long long);
} else {
ASSIGN_STREAM_LEN(stream_len, stream->buflimit,
stream->flags, long);
}
} else if (flags & FL_SHORT) {
if (flags & FL_REPD_TYPE)
*va_arg(ap, char *) = stream_len;
else
*va_arg(ap, short *) = stream_len;
if ((flags)&FL_REPD_TYPE) {
ASSIGN_STREAM_LEN(stream_len, stream->buflimit,
stream->flags, char);
} else {
ASSIGN_STREAM_LEN(stream_len, stream->buflimit,
stream->flags, short);
}
} else {
*va_arg(ap, int *) = stream_len;
ASSIGN_STREAM_LEN(stream_len, stream->buflimit,
stream->flags, int);

}
#endif
#endif
Expand Down Expand Up @@ -1249,7 +1266,9 @@ int vfprintf (FILE * stream, const CHAR *fmt, va_list ap_orig)
base = 2;
#endif
} else {
my_putc('%', stream);
while (--width > 0) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change seems unrelated to the rest of the patch?

my_putc(' ', stream);
}
my_putc(c, stream);
continue;
}
Expand Down
2 changes: 2 additions & 0 deletions newlib/libc/tinystdio/vfscanf.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,8 @@ conv_int (FILE *stream, scanf_context_t *context, width_t width, void *addr, uin
base = 16;
if (!--width || IS_EOF(i = scanf_getc (stream, context)))
goto putval;
if(!isxdigit(i))
goto err;
#ifdef _NEED_IO_PERCENT_B
} else if (i == 'b' && base <= 2) {
base = 2;
Expand Down
8 changes: 8 additions & 0 deletions newlib/libm/complex/cacoshf.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,19 @@
*/

#include <complex.h>
#include <math.h>

float complex
cacoshf(float complex z)
{
float complex w;
float x = crealf(z);
float y = cimagf(z);

if (y == 0.0f && x >= 1.0f) {
float w = acoshf(x);
return CMPLXF(w, 0.0f);
}

#if 0 /* does not give the principal value */
w = I * cacosf(z);
Expand Down
87 changes: 14 additions & 73 deletions newlib/libm/complex/casin.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,81 +85,22 @@ __weak_alias(casin, _casin)
double complex
casin(double complex z)
{
double complex w;
double complex ca, ct, zz, z2;
double x, y;

x = creal(z);
y = cimag(z);

#if 0 /* MD: test is incorrect, casin(>1) is defined */
if (y == 0.0) {
if (fabs(x) > 1.0) {
w = M_PI_2 + 0.0 * (double complex) I;
#if 0
mtherr ("casin", DOMAIN);
#endif
} else {
w = asin(x) + 0.0 * (double complex) I;
}
return w;
}
#endif

/* Power series expansion */
/*
b = cabs(z);
if( b < 0.125 )
{
z2.r = (x - y) * (x + y);
z2.i = 2.0 * x * y;

cn = 1.0;
n = 1.0;
ca.r = x;
ca.i = y;
sum.r = x;
sum.i = y;
do
{
ct.r = z2.r * ca.r - z2.i * ca.i;
ct.i = z2.r * ca.i + z2.i * ca.r;
ca.r = ct.r;
ca.i = ct.i;

cn *= n;
n += 1.0;
cn /= n;
n += 1.0;
b = cn/n;

ct.r *= b;
ct.i *= b;
sum.r += ct.r;
sum.i += ct.i;
b = fabs(ct.r) + fabs(ct.i);
}
while( b > MACHEP );
w->r = sum.r;
w->i = sum.i;
return;
}
*/
double x = creal(z);
double y = cimag(z);
double complex res;

if (x == 0.0 && y == 0.0) return z;

ca = x + y * (double complex) I;
ct = ca * (double complex) I;
/* sqrt( 1 - z*z) */
/* cmul( &ca, &ca, &zz ) */
/*x * x - y * y */
zz = (x - y) * (x + y) + (2.0 * x * y) * (double complex) I;
if (isnan(x) || isnan(y)) {
if (isinf(x) || isinf(y)) {
return CMPLX(NAN, copysign((double) INFINITY, y));
}
return CMPLX((double) NAN, (double) NAN);
}

zz = 1.0 - creal(zz) - cimag(zz) * (double complex) I;
z2 = csqrt(zz);
double complex iz = CMPLX(-y,x);
double complex w = casinh(iz);
res = CMPLX(cimag(w), - creal(w));

zz = ct + z2;
zz = clog(zz);
/* multiply by 1/i = -i */
w = zz * (-1.0 * (double complex) I);
return w;
return res;
}
87 changes: 14 additions & 73 deletions newlib/libm/complex/casinf.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,81 +42,22 @@ __weak_alias(casinf, _casinf)
float complex
casinf(float complex z)
{
float complex w;
float complex ca, ct, zz, z2;
float x, y;
float x = crealf(z);
float y = cimagf(z);
float complex res;

x = crealf(z);
y = cimagf(z);
if (x == 0.0f && y == 0.0f) return z;

#if 0 /* MD: test is incorrect, casin(>1) is defined */
if (y == 0.0f) {
if (fabsf(x) > 1.0) {
w = M_PI_2 + 0.0f * I;
#if 0
mtherr ("casin", DOMAIN);
#endif
} else {
w = asinf(x) + 0.0f * I;
}
return w;
}
#endif

/* Power series expansion */
/*
b = cabsf(z);
if( b < 0.125 )
{
z2.r = (x - y) * (x + y);
z2.i = 2.0 * x * y;

cn = 1.0;
n = 1.0;
ca.r = x;
ca.i = y;
sum.r = x;
sum.i = y;
do
{
ct.r = z2.r * ca.r - z2.i * ca.i;
ct.i = z2.r * ca.i + z2.i * ca.r;
ca.r = ct.r;
ca.i = ct.i;

cn *= n;
n += 1.0;
cn /= n;
n += 1.0;
b = cn/n;

ct.r *= b;
ct.i *= b;
sum.r += ct.r;
sum.i += ct.i;
b = fabsf(ct.r) + fabsf(ct.i);
}
while( b > MACHEP );
w->r = sum.r;
w->i = sum.i;
return;
}
*/


ca = x + y * I;
ct = ca * I;
/* sqrt( 1 - z*z) */
/* cmul( &ca, &ca, &zz ) */
/*x * x - y * y */
zz = (x - y) * (x + y) + (2.0f * x * y) * I;
if (isnanf(x) || isnanf(y)) {
if (isinff(x) || isinff(y)) {
return CMPLXF(NAN, copysignf(INFINITY, y));
}
return CMPLXF(NAN, NAN);
}

zz = 1.0f - crealf(zz) - cimagf(zz) * I;
z2 = csqrtf(zz);
float complex iz = CMPLXF(-y,x);
float complex w = casinhf(iz);
res = CMPLXF(cimagf(w), - crealf(w));

zz = ct + z2;
zz = clogf(zz);
/* multiply by 1/i = -i */
w = zz * (-1.0f * I);
return w;
return res;
}
54 changes: 51 additions & 3 deletions newlib/libm/complex/casinh.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,60 @@ QUICKREF


#include <complex.h>
#include <math.h>
#include <float.h>

double complex
casinh(double complex z)
{
double complex w;
double x = fabs(creal(z));
double y = fabs(cimag(z));
double complex res;
double complex w;

w = -1.0 * (double complex) I * casin(z * (double complex) I);
return w;
const double eps = DBL_EPSILON;

if (y == 0.0) {
if (isnan(x)) {
res = CMPLX((double) NAN, copysign(0.0, cimag(z)));
}
else if (isinf(x)) {
res = CMPLX(x, copysign(0.0, cimag(z)));
}
else {
res = CMPLX(asinh(x), copysign(0.0, cimag(z)));
}
}
/* Handle large values */
else if (x >= 1.0/eps || y >= 1.0/eps) {
res = clog(CMPLX(x, y));
res = CMPLX(creal(res) + (double) _M_LN2, cimag(res));
}

/* Case where real part >= 0.5 and imag part very samll */
else if (x >= 0.5 && y < eps/8.0) {
double s = hypot(1.0, x);
res = CMPLX(log(x + s), atan2(y, s));
}

/* Case Where real part very small and imag part >= 1.5 */
else if (x < eps/8.0 && y >= 1.5) {
double s = sqrt((y + 1.0) * (y - 1.0));
res = CMPLX(log(y + s), atan2(s, x));
}

else {
/* General case */
w = CMPLX((x - y) * (x + y) + 1.0, 2.0 * x * y);
w = csqrt(w);

w = CMPLX(x + creal(w), y + cimag(w));
res = clog(w);
}

/* Apply correct signs */
res = CMPLX(copysign(creal(res), creal(z)),
copysign(cimag(res), cimag(z)));

return res;
}
Loading