[v2,13/30] ldbl-128ibm-compat: Add ISO C99 versions of scanf functions

Message ID 20191025153410.15405-14-gabriel@inconstante.net.br
State Committed
Headers

Commit Message

Gabriel F. T. Gomes Oct. 25, 2019, 3:33 p.m. UTC
  From: "Gabriel F. T. Gomes" <gabrielftg@linux.ibm.com>

No changes since v1.

-- 8< --
In the format string for *scanf functions, the '%as', '%aS', and '%a[]'
modifiers behave differently depending on ISO C99 compatibility and on
_GNU_SOURCE.  When _GNU_SOURCE is not set and when in compatibility with
ISO C99, these modifiers consume a floating-point argument.  Otherwise,
they behave like ascanf, and allocate memory for the output.  This patch
adds the IEEE binary128 variant of these functions for the third long
double format on powerpc64le.

Tested for powerpc64le.
---
 sysdeps/ieee754/ldbl-128ibm-compat/Makefile   |  59 ++++++++-
 sysdeps/ieee754/ldbl-128ibm-compat/Versions   |  16 +++
 .../ieee128-isoc99_fscanf.c                   |  35 ++++++
 .../ieee128-isoc99_fwscanf.c                  |  35 ++++++
 .../ldbl-128ibm-compat/ieee128-isoc99_scanf.c |  35 ++++++
 .../ieee128-isoc99_sscanf.c                   |  39 ++++++
 .../ieee128-isoc99_swscanf.c                  |  40 ++++++
 .../ieee128-isoc99_vfscanf.c                  |  27 ++++
 .../ieee128-isoc99_vfwscanf.c                 |  27 ++++
 .../ieee128-isoc99_vscanf.c                   |  27 ++++
 .../ieee128-isoc99_vsscanf.c                  |  30 +++++
 .../ieee128-isoc99_vswscanf.c                 |  32 +++++
 .../ieee128-isoc99_vwscanf.c                  |  27 ++++
 .../ieee128-isoc99_wscanf.c                   |  35 ++++++
 .../test-isoc99-scanf-ibm128.c                |  13 ++
 .../test-isoc99-scanf-ieee128.c               |  13 ++
 .../test-isoc99-scanf-ldbl-compat-template.c  | 119 ++++++++++++++++++
 .../test-isoc99-scanf-ldbl-compat.c           |  10 ++
 .../test-isoc99-scanf-ldbl-compat.sh          |  53 ++++++++
 .../test-isoc99-wscanf-ibm128.c               |  13 ++
 .../test-isoc99-wscanf-ieee128.c              |  13 ++
 .../test-isoc99-wscanf-ldbl-compat.c          |  10 ++
 .../test-scanf-ldbl-compat-template.c         |   4 +
 23 files changed, 711 insertions(+), 1 deletion(-)
 create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_fscanf.c
 create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_fwscanf.c
 create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_scanf.c
 create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_sscanf.c
 create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_swscanf.c
 create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vfscanf.c
 create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vfwscanf.c
 create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vscanf.c
 create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vsscanf.c
 create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vswscanf.c
 create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vwscanf.c
 create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_wscanf.c
 create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ibm128.c
 create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ieee128.c
 create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat-template.c
 create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat.c
 create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat.sh
 create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-wscanf-ibm128.c
 create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-wscanf-ieee128.c
 create mode 100644 sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-wscanf-ldbl-compat.c
  

Comments

Paul E Murphy Nov. 8, 2019, 11:25 p.m. UTC | #1
On 10/25/19 10:33 AM, Gabriel F. T. Gomes wrote:
> From: "Gabriel F. T. Gomes" <gabrielftg@linux.ibm.com>
> 
> No changes since v1.
> 
> -- 8< --
> In the format string for *scanf functions, the '%as', '%aS', and '%a[]'
> modifiers behave differently depending on ISO C99 compatibility and on
> _GNU_SOURCE.  When _GNU_SOURCE is not set and when in compatibility with
> ISO C99, these modifiers consume a floating-point argument.  Otherwise,
> they behave like ascanf, and allocate memory for the output.  This patch
> adds the IEEE binary128 variant of these functions for the third long
> double format on powerpc64le.
> 
> Tested for powerpc64le.

git a/sysdeps/ieee754/ldbl-128ibm-compat/Makefile 
b/sysdeps/ieee754/ldbl-128ibm-compat/Makefile

OK

> diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/Versions b/sysdeps/ieee754/ldbl-128ibm-compat/Versions

OK

> diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_fscanf.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_fscanf.c

...

The various wrappers all look OK.


> +strong_alias (___ieee128_isoc99_wscanf, __isoc99_wscanfieee128)
> diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ibm128.c b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ibm128.c
> new file mode 100644
> index 0000000000..70688ac2bb
> --- /dev/null
> +++ b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ibm128.c
> @@ -0,0 +1,13 @@
> +#undef _GNU_SOURCE
> +/* The following macro definitions are a hack.  They word around disabling
> +   the GNU extension while still using a few internal headers.  */
> +#define u_char unsigned char
> +#define u_short unsigned short
> +#define u_int unsigned int
> +#define u_long unsigned long
> +#include <libio/stdio.h>
> +#include <stdlib/stdlib.h>
> +#include <string/string.h>
> +#include <wcsmbs/wchar.h>
> +
> +#include <test-isoc99-scanf-ldbl-compat.c>
> diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ieee128.c b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ieee128.c
> new file mode 100644
> index 0000000000..70688ac2bb
> --- /dev/null
> +++ b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ieee128.c
> @@ -0,0 +1,13 @@
> +#undef _GNU_SOURCE
> +/* The following macro definitions are a hack.  They word around disabling
> +   the GNU extension while still using a few internal headers.  */

Indeed a hack. How frail is this?

> +#define u_char unsigned char
> +#define u_short unsigned short
> +#define u_int unsigned int
> +#define u_long unsigned long
> +#include <libio/stdio.h>
> +#include <stdlib/stdlib.h>
> +#include <string/string.h>
> +#include <wcsmbs/wchar.h>
> +
> +#include <test-isoc99-scanf-ldbl-compat.c>
> diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat-template.c b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat-template.c
> new file mode 100644
> index 0000000000..ffc7ca2aaa
> --- /dev/null
> +++ b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat-template.c
> @@ -0,0 +1,119 @@
> +/* Test for the long double variants of __isoc99_*scanf functions.
> +   Copyright (C) 2018 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library 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
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <stdarg.h>
> +#include <stdint.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <wchar.h>
> +
> +#include <support/check.h>
> +
> +#define CLEAR_VARGS							\
> +  va_start (args, format);						\
> +  ldptr = va_arg (args, long double *);					\
> +  fptr = va_arg (args, float *);					\
> +  *ldptr = 0;								\
> +  *fptr = 0;								\
> +  va_end (args);
> +
> +#define CHECK_VARGS							\
> +  va_start (args, format);						\
> +  ldptr = va_arg (args, long double *);					\
> +  fptr = va_arg (args, float *);					\
> +  va_end (args);							\
> +  if (*ldptr == -1 && *fptr == -2)					\

Should the pointer itself also be verified?

> +    printf ("OK");							\
> +  else									\
> +    printf ("ERROR (%Lf %f)", *ldptr, *fptr);				\
> +  printf ("\n");
> +
> +#define CLEAR_VALUE							\
> +  ld = 0;								\
> +  f = 0;
> +
> +#define CHECK_VALUE							\
> +  if (ld == -1 && f == -2)						\
> +    printf ("OK");							\
> +  else									\
> +    printf ("ERROR (%Lf %f)", ld, f);					\
> +  printf ("\n");
> +
> +static void
> +do_test_call (FILE *stream, CHAR *string, const CHAR *format, ...)
> +{
> +  float *fptr;
> +  float f;
> +  long double *ldptr;
> +  long double ld;
> +  va_list args;
> +
> +  CLEAR_VALUE
> +  printf ("fscanf: ");
> +  FSCANF (stream, format, &ld, &f);
> +  CHECK_VALUE
> +
> +  CLEAR_VALUE
> +  printf ("scanf: ");
> +  SCANF (format, &ld, &f);
> +  CHECK_VALUE
> +
> +  CLEAR_VALUE
> +  printf ("sscanf: ");
> +  SSCANF (string, format, &ld, &f);
> +  CHECK_VALUE
> +
> +  CLEAR_VARGS
> +  printf ("vfscanf: ");
> +  va_start (args, format);
> +  VFSCANF (stream, format, args);
> +  va_end (args);
> +  CHECK_VARGS
> +
> +  CLEAR_VARGS
> +  printf ("vscanf: ");
> +  va_start (args, format);
> +  VSCANF (format, args);
> +  va_end (args);
> +  CHECK_VARGS
> +
> +  CLEAR_VARGS
> +  printf ("vsscanf: ");
> +  va_start (args, format);
> +  VSSCANF (string, format, args);
> +  va_end (args);
> +  CHECK_VARGS
> +}
> +
> +static int
> +do_test (void)
> +{
> +  CHAR string[256];
> +  float f;
> +  long double ld;
> +
> +  /* Scan floating-point value with '%as'.  */
> +  STRCPY (string,
> +	  L ("-0x1.0p+0 -0x2.0p+0\n")
> +	  L ("-0x1.0p+0 -0x2.0p+0\n") );
> +  do_test_call (stdin, string, L("%La %as"), &ld, &f);
> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat.c b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat.c
> diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat.sh b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat.sh

OK

ysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-wscanf-ibm128.c 
b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-wscanf-ibm128.c
> new file mode 100644
> index 0000000000..6be29624d9
> --- /dev/null
> +++ b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-wscanf-ibm128.c
> @@ -0,0 +1,13 @@
> +#undef _GNU_SOURCE
> +/* The following macro definitions are a hack.  They word around disabling
> +   the GNU extension while still using a few internal headers.  */
> +#define u_char unsigned char
> +#define u_short unsigned short
> +#define u_int unsigned int
> +#define u_long unsigned long
> +#include <libio/stdio.h>
> +#include <stdlib/stdlib.h>
> +#include <string/string.h>
> +#include <wcsmbs/wchar.h>
> +
> +#include <test-isoc99-wscanf-ldbl-compat.c>
> diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-wscanf-ieee128.c b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-wscanf-ieee128.c
> new file mode 100644
> index 0000000000..6be29624d9
> --- /dev/null
> +++ b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-wscanf-ieee128.c
> @@ -0,0 +1,13 @@
> +#undef _GNU_SOURCE
> +/* The following macro definitions are a hack.  They word around disabling
> +   the GNU extension while still using a few internal headers.  */

The same hack shows up four times, should it be isolated in one place?

> +#define u_char unsigned char
> +#define u_short unsigned short
> +#define u_int unsigned int
> +#define u_long unsigned long
> +#include <libio/stdio.h>
> +#include <stdlib/stdlib.h>
> +#include <string/string.h>
> +#include <wcsmbs/wchar.h>
> +
> +#include <test-isoc99-wscanf-ldbl-compat.c>

> diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-wscanf-ldbl-compat.c b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-wscanf-ldbl-compat.l > diff --git 
a/sysdeps/ieee754/ldbl-128ibm-compat/test-scanf-ldbl-compat-template.c 
b/sysdeps/ieee754/ldbl-128ibm-compat/test-scanf-ldbl-compat-template.c

OK
  
Gabriel F. T. Gomes Nov. 21, 2019, 1:43 p.m. UTC | #2
Hi, Paul,

I'm sorry I took so long to reply to this message.  It sent me down a
rabbit hole.

On Fri, 08 Nov 2019, Paul E Murphy wrote:
>
>On 10/25/19 10:33 AM, Gabriel F. T. Gomes wrote:
>> From: "Gabriel F. T. Gomes" <gabrielftg@linux.ibm.com>
>> 
>> --- /dev/null
>> +++ b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ieee128.c
>> @@ -0,0 +1,13 @@
>> +#undef _GNU_SOURCE
>> +/* The following macro definitions are a hack.  They word around disabling
>> +   the GNU extension while still using a few internal headers.  */  
>
>Indeed a hack. How frail is this?

A bit too much! :B

I spent some time trying to remember why I thought that was necessary and
I have a better understanding, now.

This hack is only really necessary for the wide-character versions of the
tests, because in wcsmbs/wchar.h, the redirections for vfwscanf, vwscanf,
and, more specifically, vswscanf to their ISO C99 versions is protected by
#if !defined __USE_GNU, whereas the redirections for fwscanf, wscanf, and
swscanf, as well as for all of the non-wide equivalents is protected by
#if !__GLIBC_USE (DEPRECATED_SCANF).

The use of DEPRECATED_SCANF is somewhat recent (added by commit ID
03992356e6fe) and it is my understanding that the change is missing for
vswscanf (and friends) simply due to oversight.

I have a patch to implement the missing change and I just finished running
it with build-many-glibcs.py.  I'll send it for review.

>> +#define u_char unsigned char
>> +#define u_short unsigned short
>> +#define u_int unsigned int
>> +#define u_long unsigned long
>> +#include <libio/stdio.h>
>> +#include <stdlib/stdlib.h>
>> +#include <string/string.h>
>> +#include <wcsmbs/wchar.h>
>>
>> [...]
>>
>> --- /dev/null
>> +++ b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-wscanf-ieee128.c
>> @@ -0,0 +1,13 @@
>> +#undef _GNU_SOURCE
>> +/* The following macro definitions are a hack.  They word around disabling
>> +   the GNU extension while still using a few internal headers.  */  
>
>The same hack shows up four times, should it be isolated in one place?

With the fix, I'll try and make it all go away.  Thanks for pointing that out.
  
Gabriel F. T. Gomes Nov. 22, 2019, 10:48 p.m. UTC | #3
On Thu, 21 Nov 2019, Gabriel F. T. Gomes wrote:
>
>On Fri, 08 Nov 2019, Paul E Murphy wrote:
>>
>>The same hack shows up four times, should it be isolated in one place?  
>
>With the fix, I'll try and make it all go away.  Thanks for pointing that out.

Now that commit ID 93486ba583ec is in, these hacks are gone.  I'll send a
new version of this patch, probably next week.
  
Gabriel F. T. Gomes Nov. 27, 2019, 7:12 p.m. UTC | #4
On Fri, 22 Nov 2019, Gabriel F. T. Gomes wrote:

>I'll send a new version of this patch, probably next week.

Apart from Paul's suggestions, I have also unified two test cases for
reuse, which makes the patch smaller.  I'll send the new version shortly.
  

Patch

diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/Makefile b/sysdeps/ieee754/ldbl-128ibm-compat/Makefile
index ed0e2ec098..1f944806e7 100644
--- a/sysdeps/ieee754/ldbl-128ibm-compat/Makefile
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/Makefile
@@ -6,6 +6,15 @@  ldbl-extra-routines += fwscanf \
 		       vwscanf
 endif
 
+ifeq ($(subdir),wcsmbs)
+ldbl-extra-routines += isoc99_fwscanf \
+		       isoc99_swscanf \
+		       isoc99_wscanf \
+		       isoc99_vfwscanf \
+		       isoc99_vswscanf \
+		       isoc99_vwscanf
+endif
+
 ifeq ($(subdir),stdio-common)
 ldbl-extra-routines += printf_size \
 		       asprintf \
@@ -32,7 +41,13 @@  ldbl-extra-routines += printf_size \
 		       vfscanf \
 		       vscanf \
 		       vsscanf \
-		       vfwscanf
+		       vfwscanf \
+		       isoc99_fscanf \
+		       isoc99_scanf \
+		       isoc99_sscanf \
+		       isoc99_vfscanf \
+		       isoc99_vscanf \
+		       isoc99_vsscanf
 
 # Printing long double values with IEEE binary128 format reuses part
 # of the internal float128 implementation (__printf_fp, __printf_fphex,
@@ -67,12 +82,30 @@  CFLAGS-test-wscanf-ibm128.c += -mabi=ibmlongdouble -Wno-psabi
 
 $(objpfx)test-wscanf-ieee128: gnulib-tests += $(f128-loader-link)
 
+tests-internal += test-isoc99-scanf-ieee128 test-isoc99-scanf-ibm128
+CFLAGS-test-isoc99-scanf-ieee128.c += -mfloat128 -mabi=ieeelongdouble -Wno-psabi -std=c99
+CFLAGS-test-isoc99-scanf-ibm128.c += -mabi=ibmlongdouble -Wno-psabi -std=c99
+
+$(objpfx)test-isoc99-scanf-ieee128: gnulib-tests += $(f128-loader-link)
+
+tests-internal += test-isoc99-wscanf-ieee128 test-isoc99-wscanf-ibm128
+CFLAGS-test-isoc99-wscanf-ieee128.c += -mfloat128 -mabi=ieeelongdouble -Wno-psabi -std=c99
+CFLAGS-test-isoc99-wscanf-ibm128.c += -mabi=ibmlongdouble -Wno-psabi -std=c99
+
+$(objpfx)test-isoc99-wscanf-ieee128: gnulib-tests += $(f128-loader-link)
+
 ifeq ($(run-built-tests),yes)
 tests-special += $(objpfx)test-scanf-ieee128.out
 tests-special += $(objpfx)test-scanf-ibm128.out
 
 tests-special += $(objpfx)test-wscanf-ieee128.out
 tests-special += $(objpfx)test-wscanf-ibm128.out
+
+tests-special += $(objpfx)test-isoc99-scanf-ieee128.out
+tests-special += $(objpfx)test-isoc99-scanf-ibm128.out
+
+tests-special += $(objpfx)test-isoc99-wscanf-ieee128.out
+tests-special += $(objpfx)test-isoc99-wscanf-ibm128.out
 endif
 
 $(objpfx)test-scanf-ieee128.out: \
@@ -99,6 +132,30 @@  $(objpfx)test-wscanf-ibm128.out: \
 	$(SHELL) $^ '$(test-program-prefix)' $@; \
 	$(evaluate-test)
 
+$(objpfx)test-isoc99-scanf-ieee128.out: \
+  ../sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat.sh \
+  $(objpfx)test-isoc99-scanf-ieee128
+	$(SHELL) $^ '$(test-program-prefix)' $@; \
+	$(evaluate-test)
+
+$(objpfx)test-isoc99-scanf-ibm128.out: \
+  ../sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat.sh \
+  $(objpfx)test-isoc99-scanf-ibm128
+	$(SHELL) $^ '$(test-program-prefix)' $@; \
+	$(evaluate-test)
+
+$(objpfx)test-isoc99-wscanf-ieee128.out: \
+  ../sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat.sh \
+  $(objpfx)test-isoc99-wscanf-ieee128
+	$(SHELL) $^ '$(test-program-prefix)' $@; \
+	$(evaluate-test)
+
+$(objpfx)test-isoc99-wscanf-ibm128.out: \
+  ../sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat.sh \
+  $(objpfx)test-isoc99-wscanf-ibm128
+	$(SHELL) $^ '$(test-program-prefix)' $@; \
+	$(evaluate-test)
+
 tests-internal += test-printf-size-ieee128 test-printf-size-ibm128
 CFLAGS-test-printf-size-ieee128.c += -mfloat128 -mabi=ieeelongdouble -Wno-psabi
 CFLAGS-test-printf-size-ibm128.c += -mabi=ibmlongdouble -Wno-psabi
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/Versions b/sysdeps/ieee754/ldbl-128ibm-compat/Versions
index dead38cdcb..23c2fd9793 100644
--- a/sysdeps/ieee754/ldbl-128ibm-compat/Versions
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/Versions
@@ -181,6 +181,22 @@  libc {
     __vswscanfieee128;
     __vwscanfieee128;
 
+    __isoc99_fscanfieee128;
+    __isoc99_scanfieee128;
+    __isoc99_sscanfieee128;
+
+    __isoc99_vfscanfieee128;
+    __isoc99_vscanfieee128;
+    __isoc99_vsscanfieee128;
+
+    __isoc99_fwscanfieee128;
+    __isoc99_swscanfieee128;
+    __isoc99_wscanfieee128;
+
+    __isoc99_vfwscanfieee128;
+    __isoc99_vswscanfieee128;
+    __isoc99_vwscanfieee128;
+
     __argp_errorieee128;
     __argp_failureieee128;
 
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_fscanf.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_fscanf.c
new file mode 100644
index 0000000000..3930170878
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_fscanf.c
@@ -0,0 +1,35 @@ 
+/* Wrapper for __isoc99_fscanf.  IEEE128 version.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdarg.h>
+#include <libio/libioP.h>
+
+extern int
+___ieee128_isoc99_fscanf (FILE *fp, const char *format, ...)
+{
+  va_list arg;
+  int done;
+  int mode_flags = SCANF_ISOC99_A | SCANF_LDBL_USES_FLOAT128;
+
+  va_start (arg, format);
+  done = __vfscanf_internal (fp, format, arg, mode_flags);
+  va_end (arg);
+
+  return done;
+}
+strong_alias (___ieee128_isoc99_fscanf, __isoc99_fscanfieee128)
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_fwscanf.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_fwscanf.c
new file mode 100644
index 0000000000..d56ecfbaf2
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_fwscanf.c
@@ -0,0 +1,35 @@ 
+/* Wrapper for __isoc99_fwscanf.  IEEE128 version.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdarg.h>
+#include <libioP.h>
+
+extern int
+___ieee128_isoc99_fwscanf (FILE *fp, const wchar_t *format, ...)
+{
+  va_list ap;
+  int done;
+  int mode_flags = SCANF_ISOC99_A | SCANF_LDBL_USES_FLOAT128;
+
+  va_start (ap, format);
+  done = __vfwscanf_internal (fp, format, ap, mode_flags);
+  va_end (ap);
+
+  return done;
+}
+strong_alias (___ieee128_isoc99_fwscanf, __isoc99_fwscanfieee128)
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_scanf.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_scanf.c
new file mode 100644
index 0000000000..5b643fb108
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_scanf.c
@@ -0,0 +1,35 @@ 
+/* Wrapper for __isoc99_scanf.  IEEE128 version.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdarg.h>
+#include <libio/libioP.h>
+
+extern int
+___ieee128_isoc99_scanf (const char *format, ...)
+{
+  va_list arg;
+  int done;
+  int mode_flags = SCANF_ISOC99_A | SCANF_LDBL_USES_FLOAT128;
+
+  va_start (arg, format);
+  done = __vfscanf_internal (stdin, format, arg, mode_flags);
+  va_end (arg);
+
+  return done;
+}
+strong_alias (___ieee128_isoc99_scanf, __isoc99_scanfieee128)
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_sscanf.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_sscanf.c
new file mode 100644
index 0000000000..480357ccd5
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_sscanf.c
@@ -0,0 +1,39 @@ 
+/* Wrapper for __isoc99_sscanf.  IEEE128 version.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdarg.h>
+#include <strfile.h>
+#include <libioP.h>
+
+extern int
+___ieee128_isoc99_sscanf (const char *string, const char *format, ...)
+{
+  va_list arg;
+  int done;
+  int mode_flags = SCANF_ISOC99_A | SCANF_LDBL_USES_FLOAT128;
+
+  _IO_strfile sf;
+  FILE *fp = _IO_strfile_read (&sf, string);
+
+  va_start (arg, format);
+  done = __vfscanf_internal (fp, format, arg, mode_flags);
+  va_end (arg);
+
+  return done;
+}
+strong_alias (___ieee128_isoc99_sscanf, __isoc99_sscanfieee128)
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_swscanf.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_swscanf.c
new file mode 100644
index 0000000000..e18779a986
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_swscanf.c
@@ -0,0 +1,40 @@ 
+/* Wrapper for __isoc99_swscanf.  IEEE128 version.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdarg.h>
+#include <strfile.h>
+#include <libioP.h>
+
+extern int
+___ieee128_isoc99_swscanf (const wchar_t *string, const wchar_t *format, ...)
+{
+  va_list ap;
+  int done;
+  int mode_flags = SCANF_ISOC99_A | SCANF_LDBL_USES_FLOAT128;
+
+  _IO_strfile sf;
+  struct _IO_wide_data wd;
+  FILE *fp = _IO_strfile_readw (&sf, &wd, string);
+
+  va_start (ap, format);
+  done = __vfwscanf_internal (fp, format, ap, mode_flags);
+  va_end (ap);
+
+  return done;
+}
+strong_alias (___ieee128_isoc99_swscanf, __isoc99_swscanfieee128)
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vfscanf.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vfscanf.c
new file mode 100644
index 0000000000..2d131f7fee
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vfscanf.c
@@ -0,0 +1,27 @@ 
+/* Wrapper for __isoc99_vfscanf.  IEEE128 version.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <libio/libioP.h>
+
+extern int
+___ieee128_isoc99_vfscanf (FILE *fp, const char *format, va_list ap)
+{
+  int mode_flags = SCANF_ISOC99_A | SCANF_LDBL_USES_FLOAT128;
+  return __vfscanf_internal (fp, format, ap, mode_flags);
+}
+strong_alias (___ieee128_isoc99_vfscanf, __isoc99_vfscanfieee128)
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vfwscanf.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vfwscanf.c
new file mode 100644
index 0000000000..a281ecc451
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vfwscanf.c
@@ -0,0 +1,27 @@ 
+/* Wrapper for __isoc99_vfwscanf.  IEEE128 version.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <libioP.h>
+
+extern int
+___ieee128_isoc99_vfwscanf (FILE *fp, const wchar_t *format, va_list ap)
+{
+  int mode_flags = SCANF_ISOC99_A | SCANF_LDBL_USES_FLOAT128;
+  return __vfwscanf_internal (fp, format, ap, mode_flags);
+}
+strong_alias (___ieee128_isoc99_vfwscanf, __isoc99_vfwscanfieee128)
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vscanf.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vscanf.c
new file mode 100644
index 0000000000..6ec60d5dc0
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vscanf.c
@@ -0,0 +1,27 @@ 
+/* Wrapper for __isoc99_vscanf.  IEEE128 version.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <libio/libioP.h>
+
+extern int
+___ieee128_isoc99_vscanf (const char *format, va_list ap)
+{
+  int mode_flags = SCANF_ISOC99_A | SCANF_LDBL_USES_FLOAT128;
+  return __vfscanf_internal (stdin, format, ap, mode_flags);
+}
+strong_alias (___ieee128_isoc99_vscanf, __isoc99_vscanfieee128)
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vsscanf.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vsscanf.c
new file mode 100644
index 0000000000..599e86820d
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vsscanf.c
@@ -0,0 +1,30 @@ 
+/* Wrapper for __isoc99_vsscanf.  IEEE128 version.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <strfile.h>
+#include <libioP.h>
+
+extern int
+___ieee128_isoc99_vsscanf (const char *string, const char *format, va_list ap)
+{
+  _IO_strfile sf;
+  FILE *fp = _IO_strfile_read (&sf, string);
+  int mode_flags = SCANF_ISOC99_A | SCANF_LDBL_USES_FLOAT128;
+  return __vfscanf_internal (fp, format, ap, mode_flags);
+}
+strong_alias (___ieee128_isoc99_vsscanf, __isoc99_vsscanfieee128)
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vswscanf.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vswscanf.c
new file mode 100644
index 0000000000..3a28616c26
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vswscanf.c
@@ -0,0 +1,32 @@ 
+/* Wrapper for __isoc99_vswscanf.  IEEE128 version.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <libioP.h>
+#include <wchar.h>
+#include <strfile.h>
+
+extern int
+___ieee128_isoc99_vswscanf (wchar_t *string, const wchar_t *format, va_list ap)
+{
+  _IO_strfile sf;
+  struct _IO_wide_data wd;
+  FILE *fp = _IO_strfile_readw (&sf, &wd, string);
+  int mode_flags = SCANF_ISOC99_A | SCANF_LDBL_USES_FLOAT128;
+  return __vfwscanf_internal (fp, format, ap, mode_flags);
+}
+strong_alias (___ieee128_isoc99_vswscanf, __isoc99_vswscanfieee128)
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vwscanf.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vwscanf.c
new file mode 100644
index 0000000000..b9bd4a78f0
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vwscanf.c
@@ -0,0 +1,27 @@ 
+/* Wrapper for __isoc99_vwscanf.  IEEE128 version.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <libioP.h>
+
+extern int
+___ieee128_isoc99_vwscanf (const wchar_t *format, va_list ap)
+{
+  int mode_flags = SCANF_ISOC99_A | SCANF_LDBL_USES_FLOAT128;
+  return __vfwscanf_internal (stdin, format, ap, mode_flags);
+}
+strong_alias (___ieee128_isoc99_vwscanf, __isoc99_vwscanfieee128)
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_wscanf.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_wscanf.c
new file mode 100644
index 0000000000..e78b4a3143
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_wscanf.c
@@ -0,0 +1,35 @@ 
+/* Wrapper for __isoc99_wscanf.  IEEE128 version.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdarg.h>
+#include <libioP.h>
+
+extern int
+___ieee128_isoc99_wscanf (const wchar_t *format, ...)
+{
+  va_list ap;
+  int done;
+  int mode_flags = SCANF_ISOC99_A | SCANF_LDBL_USES_FLOAT128;
+
+  va_start (ap, format);
+  done = __vfwscanf_internal (stdin, format, ap, mode_flags);
+  va_end (ap);
+
+  return done;
+}
+strong_alias (___ieee128_isoc99_wscanf, __isoc99_wscanfieee128)
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ibm128.c b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ibm128.c
new file mode 100644
index 0000000000..70688ac2bb
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ibm128.c
@@ -0,0 +1,13 @@ 
+#undef _GNU_SOURCE
+/* The following macro definitions are a hack.  They word around disabling
+   the GNU extension while still using a few internal headers.  */
+#define u_char unsigned char
+#define u_short unsigned short
+#define u_int unsigned int
+#define u_long unsigned long
+#include <libio/stdio.h>
+#include <stdlib/stdlib.h>
+#include <string/string.h>
+#include <wcsmbs/wchar.h>
+
+#include <test-isoc99-scanf-ldbl-compat.c>
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ieee128.c b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ieee128.c
new file mode 100644
index 0000000000..70688ac2bb
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ieee128.c
@@ -0,0 +1,13 @@ 
+#undef _GNU_SOURCE
+/* The following macro definitions are a hack.  They word around disabling
+   the GNU extension while still using a few internal headers.  */
+#define u_char unsigned char
+#define u_short unsigned short
+#define u_int unsigned int
+#define u_long unsigned long
+#include <libio/stdio.h>
+#include <stdlib/stdlib.h>
+#include <string/string.h>
+#include <wcsmbs/wchar.h>
+
+#include <test-isoc99-scanf-ldbl-compat.c>
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat-template.c b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat-template.c
new file mode 100644
index 0000000000..ffc7ca2aaa
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat-template.c
@@ -0,0 +1,119 @@ 
+/* Test for the long double variants of __isoc99_*scanf functions.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <wchar.h>
+
+#include <support/check.h>
+
+#define CLEAR_VARGS							\
+  va_start (args, format);						\
+  ldptr = va_arg (args, long double *);					\
+  fptr = va_arg (args, float *);					\
+  *ldptr = 0;								\
+  *fptr = 0;								\
+  va_end (args);
+
+#define CHECK_VARGS							\
+  va_start (args, format);						\
+  ldptr = va_arg (args, long double *);					\
+  fptr = va_arg (args, float *);					\
+  va_end (args);							\
+  if (*ldptr == -1 && *fptr == -2)					\
+    printf ("OK");							\
+  else									\
+    printf ("ERROR (%Lf %f)", *ldptr, *fptr);				\
+  printf ("\n");
+
+#define CLEAR_VALUE							\
+  ld = 0;								\
+  f = 0;
+
+#define CHECK_VALUE							\
+  if (ld == -1 && f == -2)						\
+    printf ("OK");							\
+  else									\
+    printf ("ERROR (%Lf %f)", ld, f);					\
+  printf ("\n");
+
+static void
+do_test_call (FILE *stream, CHAR *string, const CHAR *format, ...)
+{
+  float *fptr;
+  float f;
+  long double *ldptr;
+  long double ld;
+  va_list args;
+
+  CLEAR_VALUE
+  printf ("fscanf: ");
+  FSCANF (stream, format, &ld, &f);
+  CHECK_VALUE
+
+  CLEAR_VALUE
+  printf ("scanf: ");
+  SCANF (format, &ld, &f);
+  CHECK_VALUE
+
+  CLEAR_VALUE
+  printf ("sscanf: ");
+  SSCANF (string, format, &ld, &f);
+  CHECK_VALUE
+
+  CLEAR_VARGS
+  printf ("vfscanf: ");
+  va_start (args, format);
+  VFSCANF (stream, format, args);
+  va_end (args);
+  CHECK_VARGS
+
+  CLEAR_VARGS
+  printf ("vscanf: ");
+  va_start (args, format);
+  VSCANF (format, args);
+  va_end (args);
+  CHECK_VARGS
+
+  CLEAR_VARGS
+  printf ("vsscanf: ");
+  va_start (args, format);
+  VSSCANF (string, format, args);
+  va_end (args);
+  CHECK_VARGS
+}
+
+static int
+do_test (void)
+{
+  CHAR string[256];
+  float f;
+  long double ld;
+
+  /* Scan floating-point value with '%as'.  */
+  STRCPY (string,
+	  L ("-0x1.0p+0 -0x2.0p+0\n")
+	  L ("-0x1.0p+0 -0x2.0p+0\n") );
+  do_test_call (stdin, string, L("%La %as"), &ld, &f);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat.c b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat.c
new file mode 100644
index 0000000000..739b6bb479
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat.c
@@ -0,0 +1,10 @@ 
+#define CHAR char
+#define L(x) x
+#define FSCANF fscanf
+#define SSCANF sscanf
+#define SCANF scanf
+#define VFSCANF vfscanf
+#define VSSCANF vsscanf
+#define VSCANF vscanf
+#define STRCPY strcpy
+#include <test-isoc99-scanf-ldbl-compat-template.c>
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat.sh b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat.sh
new file mode 100644
index 0000000000..fc08beddc5
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-scanf-ldbl-compat.sh
@@ -0,0 +1,53 @@ 
+#!/bin/sh
+# Testing of __isoc99_*scanf.  IEEE binary128 for powerpc64le version.
+# Copyright (C) 2018 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library 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
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+set -e
+
+test_program=$1; shift
+test_program_prefix=$1; shift
+test_program_output=$1; shift
+
+status=0
+
+cat <<'EOF' |
+-0x1.0p+0 -0x2.0p+0
+-0x1.0p+0 -0x2.0p+0
+-0x1.0p+0 -0x2.0p+0
+-0x1.0p+0 -0x2.0p+0
+EOF
+${test_program_prefix} \
+  ${test_program} \
+  - \
+  > ${test_program_output} || status=1
+
+cat <<'EOF' |
+fscanf: OK
+scanf: OK
+sscanf: OK
+vfscanf: OK
+vscanf: OK
+vsscanf: OK
+EOF
+cmp - ${test_program_output} > /dev/null 2>&1 ||
+{
+  status=1
+  echo "*** output comparison failed"
+}
+
+exit $status
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-wscanf-ibm128.c b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-wscanf-ibm128.c
new file mode 100644
index 0000000000..6be29624d9
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-wscanf-ibm128.c
@@ -0,0 +1,13 @@ 
+#undef _GNU_SOURCE
+/* The following macro definitions are a hack.  They word around disabling
+   the GNU extension while still using a few internal headers.  */
+#define u_char unsigned char
+#define u_short unsigned short
+#define u_int unsigned int
+#define u_long unsigned long
+#include <libio/stdio.h>
+#include <stdlib/stdlib.h>
+#include <string/string.h>
+#include <wcsmbs/wchar.h>
+
+#include <test-isoc99-wscanf-ldbl-compat.c>
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-wscanf-ieee128.c b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-wscanf-ieee128.c
new file mode 100644
index 0000000000..6be29624d9
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-wscanf-ieee128.c
@@ -0,0 +1,13 @@ 
+#undef _GNU_SOURCE
+/* The following macro definitions are a hack.  They word around disabling
+   the GNU extension while still using a few internal headers.  */
+#define u_char unsigned char
+#define u_short unsigned short
+#define u_int unsigned int
+#define u_long unsigned long
+#include <libio/stdio.h>
+#include <stdlib/stdlib.h>
+#include <string/string.h>
+#include <wcsmbs/wchar.h>
+
+#include <test-isoc99-wscanf-ldbl-compat.c>
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-wscanf-ldbl-compat.c b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-wscanf-ldbl-compat.c
new file mode 100644
index 0000000000..3ad29645f6
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/test-isoc99-wscanf-ldbl-compat.c
@@ -0,0 +1,10 @@ 
+#define CHAR wchar_t
+#define L(x) L##x
+#define FSCANF fwscanf
+#define SSCANF swscanf
+#define SCANF wscanf
+#define VFSCANF vfwscanf
+#define VSSCANF vswscanf
+#define VSCANF vwscanf
+#define STRCPY wcscpy
+#include <test-isoc99-scanf-ldbl-compat-template.c>
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/test-scanf-ldbl-compat-template.c b/sysdeps/ieee754/ldbl-128ibm-compat/test-scanf-ldbl-compat-template.c
index 4590e9da96..aea4f0d358 100644
--- a/sysdeps/ieee754/ldbl-128ibm-compat/test-scanf-ldbl-compat-template.c
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/test-scanf-ldbl-compat-template.c
@@ -53,8 +53,10 @@  static void
 do_test_call (FILE *stream, CHAR *string, const CHAR *format, ...)
 {
   long double value;
+#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
   long double *ld;
   va_list args;
+#endif
 
   CLEAR_VALUE
   printf ("fscanf: ");
@@ -71,6 +73,7 @@  do_test_call (FILE *stream, CHAR *string, const CHAR *format, ...)
   SSCANF (string, format, &value);
   CHECK_VALUE
 
+#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
   CLEAR
   printf ("vfscanf: ");
   va_start (args, format);
@@ -91,6 +94,7 @@  do_test_call (FILE *stream, CHAR *string, const CHAR *format, ...)
   VSSCANF (string, format, args);
   va_end (args);
   CHECK
+#endif
 }
 
 static int