Skip to content
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

[PATCH] Add optional GCC-only support for using long doubles on Win32 #14204

Closed
p5pRT opened this issue Nov 3, 2014 · 38 comments
Closed

[PATCH] Add optional GCC-only support for using long doubles on Win32 #14204

p5pRT opened this issue Nov 3, 2014 · 38 comments

Comments

@p5pRT
Copy link

p5pRT commented Nov 3, 2014

Migrated from rt.perl.org#123113 (status was 'resolved')

Searchable as RT123113$

@p5pRT
Copy link
Author

p5pRT commented Nov 3, 2014

From @steve-m-hay

The attached patch attempts to add optional GCC-only support for using long doubles on Win32, but doesn't quite work and I can't figure out why not. When building with the command "dmake USE_LONG_DOUBLE=define" we get a miniperl.exe created, but when it is used to run the command "..\miniperl.exe -I..\lib -f ..\write_buildcustomize.pl .." it fails like this​:

Invalid version format (negative version number) at lib/vars.pm line 3.
BEGIN failed--compilation aborted at lib/vars.pm line 3.
Compilation failed in require at dist/PathTools/lib/File/Spec.pm line 4.
BEGIN failed--compilation aborted at dist/PathTools/lib/File/Spec.pm line 4.
Compilation failed in require at dist/PathTools/lib/File/Spec/Functions.pm line 3.
BEGIN failed--compilation aborted at dist/PathTools/lib/File/Spec/Functions.pm line 3.
Compilation failed in require at ..\write_buildcustomize.pl line 49.
dmake​: Error code 255, while making '..\lib\buildcustomize.pl'

This "Invalid version format" error is typical of messing up the floating point routines (stringify/numify), but I haven't figured out exactly what the problem is yet. I'm recording what I've got so far in this ticket so that it doesn't get lost.

@p5pRT
Copy link
Author

p5pRT commented Nov 3, 2014

From @steve-m-hay

0001-Add-optional-GCC-only-support-for-using-long-doubles.patch
From e1b480c084792aaab40916f6c6772bddf665df76 Mon Sep 17 00:00:00 2001
From: Steve Hay <steve.m.hay@googlemail.com>
Date: Fri, 19 Sep 2014 17:49:51 +0100
Subject: [PATCH] Add optional GCC-only support for using long doubles on Win32

---
 win32/Makefile     |  4 +++
 win32/config.gc    | 14 +++++-----
 win32/config_H.gc  |  8 +++---
 win32/config_sh.PL | 44 ++++++++++++++++++++++++++++++--
 win32/makefile.mk  | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 5 files changed, 131 insertions(+), 14 deletions(-)

diff --git a/win32/Makefile b/win32/Makefile
index 16585b2..e5c3c86 100644
--- a/win32/Makefile
+++ b/win32/Makefile
@@ -26,6 +26,7 @@ INST_TOP	= $(INST_DRV)\perl
 #
 # Uncomment if you want to build a 32-bit Perl using a 32-bit compiler
 # on a 64-bit version of Windows.
+#
 #WIN64		= undef
 
 #
@@ -85,12 +86,14 @@ USE_IMP_SYS	= define
 # then get a number of fails from make test i.e. bugs - complain to them not us ;-). 
 # You will also be unable to take full advantage of perl5.8's support for multiple 
 # encodings and may see lower IO performance. You have been warned.
+#
 USE_PERLIO	= define
 
 #
 # Comment this out if you don't want to enable large file support for
 # some reason.  Should normally only be changed to maintain compatibility
 # with an older release of perl.
+#
 USE_LARGE_FILES	= define
 
 #
@@ -98,6 +101,7 @@ USE_LARGE_FILES	= define
 # (If you're building a 64-bit perl then you will have 64-bit integers whether
 # or not this is uncommented.)
 # Note: This option is not supported in 32-bit MSVC60 builds.
+#
 #USE_64_BIT_INT	= define
 
 #
diff --git a/win32/config.gc b/win32/config.gc
index b57a243..45c4f1b 100644
--- a/win32/config.gc
+++ b/win32/config.gc
@@ -913,19 +913,19 @@ sGMTIME_max="2147483647"
 sGMTIME_min="0"
 sLOCALTIME_max="2147483647"
 sLOCALTIME_min="0"
-sPRIEUldbl='"E"'
-sPRIFUldbl='"F"'
-sPRIGUldbl='"G"'
+sPRIEUldbl='"LE"'
+sPRIFUldbl='"LF"'
+sPRIGUldbl='"LG"'
 sPRIXU64='"lX"'
 sPRId64='"ld"'
-sPRIeldbl='"e"'
-sPRIfldbl='"f"'
-sPRIgldbl='"g"'
+sPRIeldbl='"Le"'
+sPRIfldbl='"Lf"'
+sPRIgldbl='"Lg"'
 sPRIi64='"li"'
 sPRIo64='"lo"'
 sPRIu64='"lu"'
 sPRIx64='"lx"'
-sSCNfldbl='"f"'
+sSCNfldbl='"Lf"'
 sched_yield=''
 scriptdir='~INST_TOP~~INST_VER~\bin'
 scriptdirexp='~INST_TOP~~INST_VER~\bin'
diff --git a/win32/config_H.gc b/win32/config_H.gc
index abb1f9e..e70800a 100644
--- a/win32/config_H.gc
+++ b/win32/config_H.gc
@@ -4500,10 +4500,10 @@
  *	This symbol, if defined, contains the string used by stdio to
  *	format long doubles (format 'f') for input.
  */
-/*#define PERL_PRIfldbl	"f"	/ **/
-/*#define PERL_PRIgldbl	"g"	/ **/
-/*#define PERL_PRIeldbl	"e"	/ **/
-/*#define PERL_SCNfldbl	"f"	/ **/
+/*#define PERL_PRIfldbl	"Lf"	/ **/
+/*#define PERL_PRIgldbl	"Lg"	/ **/
+/*#define PERL_PRIeldbl	"Le"	/ **/
+/*#define PERL_SCNfldbl	"Lf"	/ **/
 
 /* NEED_VA_COPY:
  *	This symbol, if defined, indicates that the system stores
diff --git a/win32/config_sh.PL b/win32/config_sh.PL
index f20be97..ef6ad32 100644
--- a/win32/config_sh.PL
+++ b/win32/config_sh.PL
@@ -151,12 +151,20 @@ else {
     $opt{ssizetype} = 'int';
     $opt{st_ino_size} = 4;
 }
+
+# set 64-bit-int options
 if ($opt{use64bitint} eq 'define') {
-    $opt{d_nv_preserves_uv} = 'undef';
+    if ($opt{uselongdouble} eq 'define') {
+        $opt{d_nv_preserves_uv} = 'define';
+        $opt{nv_preserves_uv_bits} = 64;
+    }
+    else {
+        $opt{d_nv_preserves_uv} = 'undef';
+        $opt{nv_preserves_uv_bits} = 53;
+    }
     $opt{ivdformat} = qq{"I64d"};
     $opt{ivsize} = 8;
     $opt{ivtype} = $int64;
-    $opt{nv_preserves_uv_bits} = 53;
     $opt{sPRIXU64} = qq{"I64X"};
     $opt{sPRId64} = qq{"I64d"};
     $opt{sPRIi64} = qq{"I64i"};
@@ -190,6 +198,38 @@ else {
     $opt{uvxformat} = '"lx"';
 }
 
+# set long double options
+if ($opt{uselongdouble} eq 'define') {
+    $opt{d_frexpl} = 'define';
+    $opt{d_isnanl} = 'define';
+    $opt{d_modfl} = 'define';
+    $opt{d_modflproto} = 'define';
+    $opt{d_sqrtl} = 'define';
+    $opt{d_strtold} = 'define';
+    $opt{d_PRIeldbl} = 'define';
+    $opt{d_PRIfldbl} = 'define';
+    $opt{d_PRIgldbl} = 'define';
+    $opt{d_SCNfldbl} = 'define';
+    $opt{nvsize} = 12;
+    $opt{nvtype} = 'long double';
+    $opt{nv_overflows_integers_at} = '256.0*256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0*2.0*2.0*2.0';
+}
+else {
+    $opt{d_frexpl} = 'undef';
+    $opt{d_isnanl} = 'undef';
+    $opt{d_modfl} = 'undef';
+    $opt{d_modflproto} = 'undef';
+    $opt{d_sqrtl} = 'undef';
+    $opt{d_strtold} = 'undef';
+    $opt{d_PRIeldbl} = 'undef';
+    $opt{d_PRIfldbl} = 'undef';
+    $opt{d_PRIgldbl} = 'undef';
+    $opt{d_SCNfldbl} = 'undef';
+    $opt{nvsize} = 8;
+    $opt{nvtype} = 'double';
+    $opt{nv_overflows_integers_at} = '256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0';
+}
+
 # change the s{GM|LOCAL}TIME_{min|max} for VS2005 (aka VC 8) and
 # VS2008 (aka VC 9) or higher (presuming that later versions will have
 # at least the range of that).
diff --git a/win32/makefile.mk b/win32/makefile.mk
index 5a69973..2f1d550 100644
--- a/win32/makefile.mk
+++ b/win32/makefile.mk
@@ -32,6 +32,7 @@ INST_TOP	*= $(INST_DRV)\perl
 #
 # Uncomment if you want to build a 32-bit Perl using a 32-bit compiler
 # on a 64-bit version of Windows.
+#
 #WIN64		*= undef
 
 #
@@ -91,12 +92,14 @@ USE_IMP_SYS	*= define
 # then get a number of fails from make test i.e. bugs - complain to them not us ;-). 
 # You will also be unable to take full advantage of perl5.8's support for multiple 
 # encodings and may see lower IO performance. You have been warned.
+#
 USE_PERLIO	*= define
 
 #
 # Comment this out if you don't want to enable large file support for
 # some reason.  Should normally only be changed to maintain compatibility
 # with an older release of perl.
+#
 USE_LARGE_FILES	*= define
 
 #
@@ -104,9 +107,16 @@ USE_LARGE_FILES	*= define
 # (If you're building a 64-bit perl then you will have 64-bit integers whether
 # or not this is uncommented.)
 # Note: This option is not supported in 32-bit MSVC60 builds.
+#
 #USE_64_BIT_INT	*= define
 
 #
+# Uncomment this if you want to support the use of long doubles in GCC builds.
+# This option is not supported for MSVC builds.
+#
+#USE_LONG_DOUBLE *=define
+
+#
 # uncomment exactly one of the following
 #
 # Visual C++ 6.x (aka Visual C++ 98)
@@ -292,6 +302,7 @@ USE_IMP_SYS	*= undef
 USE_PERLIO	*= undef
 USE_LARGE_FILES	*= undef
 USE_64_BIT_INT	*= undef
+USE_LONG_DOUBLE	*= undef
 
 .IF "$(USE_IMP_SYS)" == "define"
 PERL_MALLOC	= undef
@@ -358,6 +369,12 @@ CCTYPE		= SDK2003SP1
 USE_64_BIT_INT	!= undef
 .ENDIF
 
+# Disable the long double option for MSVC builds since that compiler
+# does not support it.
+.IF "$(CCTYPE)" != "GCC"
+USE_LONG_DOUBLE	!= undef
+.ENDIF
+
 ARCHITECTURE = $(PROCESSOR_ARCHITECTURE)
 .IF "$(ARCHITECTURE)" == "AMD64"
 ARCHITECTURE	= x64
@@ -428,6 +445,11 @@ LIB32		= $(ARCHPREFIX)ar rc
 IMPLIB		= $(ARCHPREFIX)dlltool
 RSC		= $(ARCHPREFIX)windres
 
+.IF "$(USE_LONG_DOUBLE)" == "define"
+BUILDOPT        += -D__USE_MINGW_ANSI_STDIO
+MINIBUILDOPT    += -D__USE_MINGW_ANSI_STDIO
+.ENDIF
+
 GCCWRAPV *= $(shell for /f "delims=. tokens=1,2,3" %i in ('$(CC) -dumpversion') do @if "%i"=="4" (if "%j" geq "3" echo define) else if "%i" geq "5" (echo define))
 
 .IF "$(GCCWRAPV)" == "define"
@@ -949,6 +971,7 @@ CFG_VARS	=					\
 		usemultiplicity=$(USE_MULTI)	~	\
 		useperlio=$(USE_PERLIO)		~	\
 		use64bitint=$(USE_64_BIT_INT)	~	\
+		uselongdouble=$(USE_LONG_DOUBLE)	~	\
 		uselargefiles=$(USE_LARGE_FILES)	~	\
 		usesitecustomize=$(USE_SITECUST)	~	\
 		LINK_FLAGS=$(LINK_FLAGS)	~	\
@@ -1024,6 +1047,7 @@ config.w32 : $(CFGSH_TMPL)
 	@echo #undef HAS_ATOLL>>$@
 	@echo #undef HAS_STRTOLL>>$@
 	@echo #undef HAS_STRTOULL>>$@
+	@echo #undef Size_t_size>>$@
 	@echo #undef IVTYPE>>$@
 	@echo #undef UVTYPE>>$@
 	@echo #undef IVSIZE>>$@
@@ -1036,7 +1060,20 @@ config.w32 : $(CFGSH_TMPL)
 	@echo #undef UVxf>>$@
 	@echo #undef UVXf>>$@
 	@echo #undef USE_64_BIT_INT>>$@
-	@echo #undef Size_t_size>>$@
+	@echo #undef HAS_FREXPL>>$@
+	@echo #undef HAS_ISNANL>>$@
+	@echo #undef HAS_MODFL>>$@
+	@echo #undef HAS_MODFL_PROTO>>$@
+	@echo #undef HAS_SQRTL>>$@
+	@echo #undef HAS_STRTOLD>>$@
+	@echo #undef PERL_PRIfldbl>>$@
+	@echo #undef PERL_PRIgldbl>>$@
+	@echo #undef PERL_PRIeldbl>>$@
+	@echo #undef PERL_SCNfldbl>>$@
+	@echo #undef NVTYPE>>$@
+	@echo #undef NVSIZE>>$@
+	@echo #undef NV_OVERFLOWS_INTEGERS_AT>>$@
+	@echo #undef USE_LONG_DOUBLE>>$@
 .IF "$(USE_LARGE_FILES)"=="define"
 	@echo #define Off_t $(INT64)>>$@
 	@echo #define LSEEKSIZE ^8>>$@
@@ -1066,8 +1103,13 @@ config.w32 : $(CFGSH_TMPL)
 	@echo #define UVTYPE unsigned $(INT64)>>$@
 	@echo #define IVSIZE ^8>>$@
 	@echo #define UVSIZE ^8>>$@
+.IF "$(USE_LONG_DOUBLE)"=="define"
+	@echo #define NV_PRESERVES_UV>>$@
+	@echo #define NV_PRESERVES_UV_BITS 64>>$@
+.ELSE
 	@echo #undef NV_PRESERVES_UV>>$@
 	@echo #define NV_PRESERVES_UV_BITS 53>>$@
+.ENDIF
 	@echo #define IVdf "I64d">>$@
 	@echo #define UVuf "I64u">>$@
 	@echo #define UVof "I64o">>$@
@@ -1088,6 +1130,37 @@ config.w32 : $(CFGSH_TMPL)
 	@echo #define UVXf "lX">>$@
 	@echo #undef USE_64_BIT_INT>>$@
 .ENDIF
+.IF "$(USE_LONG_DOUBLE)"=="define"
+	@echo #define HAS_FREXPL>>$@
+	@echo #define HAS_ISNANL>>$@
+	@echo #define HAS_MODFL>>$@
+	@echo #define HAS_MODFL_PROTO>>$@
+	@echo #define HAS_SQRTL>>$@
+	@echo #define HAS_STRTOLD>>$@
+	@echo #define PERL_PRIfldbl "Lf">>$@
+	@echo #define PERL_PRIgldbl "Lg">>$@
+	@echo #define PERL_PRIeldbl "Le">>$@
+	@echo #define PERL_SCNfldbl "Lf">>$@
+	@echo #define NVTYPE long double>>$@
+	@echo #define NVSIZE ^12>>$@
+	@echo #define NV_OVERFLOWS_INTEGERS_AT 256.0*256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0*2.0*2.0*2.0>>$@
+	@echo #define USE_LONG_DOUBLE>>$@
+.ELSE
+	@echo #undef HAS_FREXPL>>$@
+	@echo #undef HAS_ISNANL>>$@
+	@echo #undef HAS_MODFL>>$@
+	@echo #undef HAS_MODFL_PROTO>>$@
+	@echo #undef HAS_SQRTL>>$@
+	@echo #undef HAS_STRTOLD>>$@
+	@echo #undef PERL_PRIfldbl>>$@
+	@echo #undef PERL_PRIgldbl>>$@
+	@echo #undef PERL_PRIeldbl>>$@
+	@echo #undef PERL_SCNfldbl>>$@
+	@echo #define NVTYPE double>>$@
+	@echo #define NVSIZE ^8>>$@
+	@echo #define NV_OVERFLOWS_INTEGERS_AT 256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0>>$@
+	@echo #undef USE_LONG_DOUBLE>>$@
+.ENDIF
 	@echo #endif>>$@
 
 ..\git_version.h : $(MINIPERL) ..\make_patchnum.pl
-- 
1.8.4.msysgit.0

@p5pRT
Copy link
Author

p5pRT commented Nov 4, 2014

From @bulk88

On Mon Nov 03 00​:55​:36 2014, shay wrote​:

The attached patch attempts to add optional GCC-only support for using
long doubles on Win32, but doesn't quite work and I can't figure out
why not. When building with the command "dmake USE_LONG_DOUBLE=define"
we get a miniperl.exe created, but when it is used to run the command
"..\miniperl.exe -I..\lib -f ..\write_buildcustomize.pl .." it fails
like this​:

Invalid version format (negative version number) at lib/vars.pm line
3.
BEGIN failed--compilation aborted at lib/vars.pm line 3.
Compilation failed in require at dist/PathTools/lib/File/Spec.pm line
4.
BEGIN failed--compilation aborted at dist/PathTools/lib/File/Spec.pm
line 4.
Compilation failed in require at
dist/PathTools/lib/File/Spec/Functions.pm line 3.
BEGIN failed--compilation aborted at
dist/PathTools/lib/File/Spec/Functions.pm line 3.
Compilation failed in require at ..\write_buildcustomize.pl line 49.
dmake​: Error code 255, while making '..\lib\buildcustomize.pl'

This "Invalid version format" error is typical of messing up the
floating point routines (stringify/numify), but I haven't figured out
exactly what the problem is yet. I'm recording what I've got so far in
this ticket so that it doesn't get lost.

I hit that when I tried to make Intel C long double build. The problem is MS CRT silently accepts %lf as a 8 byte double (the #ifdefs in the CRT source wind up with %lf being identical to %f) on C stack, not a 12 byte double on C stack. va_arg macro/function incorrectly advances the va_list ptr, and all further var args are gibberish too.

Mingw offers its own printf/etc for static linking into your binary, which is 12 byte long double compliant. ICC doesn't have an equivalent printf, so I tried using the mingw's .o to make the long double aware printf get linked in and then gave up (i'd have to separate the printf symbols from the .o from the rest of mingw's CRT static link code, and then I realized I might as well compile it from scratch, then I gave up). i attached a patch of how far I got.

The sad thing is MS CRT's source code has provisions for long doubles, it is just not compiled in by default. Win16 and Visual C for Win16 and MS C for DOS has 12 byte long doubles. MS seems to have discontinued them during the switch to Win32.

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Nov 4, 2014

From @bulk88

0001-icc-longdouble-wip.patch
From 6d149aa0e5feff84216d4da035c7f1b2278e81bc Mon Sep 17 00:00:00 2001
From: Daniel Dragan <bulk88@hotmail.com>
Date: Thu, 9 Jan 2014 03:10:40 -0500
Subject: [PATCH] icc longdouble wip

---
 generate_uudmap.c |  2 ++
 perl.h            | 12 ++++++++++++
 uconfig.h         |  8 ++++----
 util.c            |  9 +++++++--
 win32/Makefile    | 10 +++++-----
 win32/config.vc   | 18 +++++++++---------
 win32/config_H.vc | 30 +++++++++++++++---------------
 7 files changed, 54 insertions(+), 35 deletions(-)

diff --git a/generate_uudmap.c b/generate_uudmap.c
index b6307c0..b72f374 100644
--- a/generate_uudmap.c
+++ b/generate_uudmap.c
@@ -108,6 +108,8 @@ int main(int argc, char **argv) {
   int bits;
   struct mg_data_raw_t *p = mg_data_raw;
 
+    fprintf(stderr, "sizeof ld %d\n", sizeof(long double));
+
   if (argc < 4 || argv[1][0] == '\0' || argv[2][0] == '\0'
       || argv[3][0] == '\0') {
     fprintf(stderr, "Usage: %s uudemap.h bitcount.h mg_data.h\n", argv[0]);
diff --git a/perl.h b/perl.h
index b6e0c3e..6c7d5bd 100644
--- a/perl.h
+++ b/perl.h
@@ -1671,6 +1671,7 @@ typedef UVTYPE UV;
 #  endif
 #  if !(defined(HAS_LONG_DOUBLE) && (LONG_DOUBLESIZE > DOUBLESIZE))
 #     undef USE_LONG_DOUBLE /* Ouch! */
+      #error undefed ULD
 #  endif
 #endif
 
@@ -1763,10 +1764,15 @@ typedef NVTYPE NV;
 #   include <ieeefp.h>
 #endif
 
+#ifndef USE_LONG_DOUBLE
+#error no LD
+#endif
+
 #ifdef USE_LONG_DOUBLE
 #   ifdef I_SUNMATH
 #       include <sunmath.h>
 #   endif
+#   include <mathimf.h>
 #   define NV_DIG LDBL_DIG
 #   ifdef LDBL_MANT_DIG
 #       define NV_MANT_DIG LDBL_MANT_DIG
@@ -1798,6 +1804,7 @@ typedef NVTYPE NV;
 #           endif
 #       endif
 #   endif
+
 #   ifdef HAS_SQRTL
 #       define Perl_cos cosl
 #       define Perl_sin sinl
@@ -1843,6 +1850,7 @@ EXTERN_C long double modfl(long double, long double *);
 #       endif
 #   endif
 #else
+#error die
 #   define NV_DIG DBL_DIG
 #   ifdef DBL_MANT_DIG
 #       define NV_MANT_DIG DBL_MANT_DIG
@@ -5833,6 +5841,10 @@ extern void moncontrol(int);
 
 */
 
+#ifndef HAS_SQRTL
+#error no long
+#endif
+
 #endif /* Include guard */
 
 /*
diff --git a/uconfig.h b/uconfig.h
index 8e728ab..e29fabd 100644
--- a/uconfig.h
+++ b/uconfig.h
@@ -4361,10 +4361,10 @@
  *	This symbol, if defined, contains the string used by stdio to
  *	format long doubles (format 'f') for input.
  */
-/*#define PERL_PRIfldbl	"llf"	/ **/
-/*#define PERL_PRIgldbl	"llg"	/ **/
-/*#define PERL_PRIeldbl	"lle"	/ **/
-/*#define PERL_SCNfldbl	"llf"	/ **/
+#define PERL_PRIfldbl	"llf"	/ **/
+#define PERL_PRIgldbl	"llg"	/ **/
+#define PERL_PRIeldbl	"lle"	/ **/
+#define PERL_SCNfldbl	"llf"	/ **/
 
 /* PERL_MAD:
  *	This symbol, if defined, indicates that the Misc Attribution
diff --git a/util.c b/util.c
index f308e93..455b7bb 100644
--- a/util.c
+++ b/util.c
@@ -4769,10 +4769,12 @@ Perl_my_snprintf(char *buffer, const Size_t len, const char *format, ...)
 {
     int retval;
     va_list ap;
+    restart:
     PERL_ARGS_ASSERT_MY_SNPRINTF;
     va_start(ap, format);
+    memset(buffer, 0, len);
 #ifdef HAS_VSNPRINTF
-    retval = vsnprintf(buffer, len, format, ap);
+    retval = ___mingw_vsnprintf(buffer, len, format, ap);
 #else
     retval = vsprintf(buffer, format, ap);
 #endif
@@ -4784,8 +4786,11 @@ Perl_my_snprintf(char *buffer, const Size_t len, const char *format, ...)
         ||
         (len > 0 && (Size_t)retval >= len) 
 #endif
-    )
+    ) {
+	DebugBreak();
+	goto restart;
 	Perl_croak_nocontext("panic: my_snprintf buffer overflow");
+    }
     return retval;
 }
 
diff --git a/win32/Makefile b/win32/Makefile
index 885f8ce..2c90bef 100644
--- a/win32/Makefile
+++ b/win32/Makefile
@@ -134,14 +134,14 @@ CCTYPE		= MSVC90
 #
 # If you are using Intel C++ Compiler uncomment this
 #
-#__ICC		= define
+__ICC		= define
 
 #
 # uncomment next line if you want debug version of perl (big,slow)
 # If not enabled, we automatically try to use maximum optimization
 # with all compilers that are known to have a working optimizer.
 #
-#CFG		= Debug
+CFG		= Debug
 
 #
 # uncomment to enable linking with setargv.obj under the Visual C
@@ -443,10 +443,10 @@ LOCDEFS		= -DPERLDLL -DPERL_CORE
 SUBSYS		= console
 CXX_FLAG	= -TP -EHsc
 
-LIBC	= msvcrt.lib
+LIBC	= msvcrtd.lib
 
 !IF  "$(CFG)" == "Debug"
-OPTIMIZE	= -Od -MD -Zi -DDEBUGGING
+OPTIMIZE	= -Od -MDd -Zi -DDEBUGGING
 LINK_DBG	= -debug
 !ELSE
 # -O1 yields smaller code, which turns out to be faster than -O2 on x86 and x64
@@ -517,7 +517,7 @@ LIBBASEFILES    = $(LIBBASEFILES) bufferoverflowU.lib
 LIBFILES	= $(LIBBASEFILES) $(LIBC)
 
 #EXTRACFLAGS	= -nologo -GF -W4 -wd4127 -wd4706
-EXTRACFLAGS	= -nologo -GF -W3
+EXTRACFLAGS	= -nologo -GF -W3 /Qlong-double /Qpc80 -DUSE_LONG_DOUBLE -DHAS_LONG_DOUBLE
 CFLAGS		= $(EXTRACFLAGS) $(INCLUDES) $(DEFINES) $(LOCDEFS) \
 		$(PCHFLAGS) $(OPTIMIZE)
 LINK_FLAGS	= -nologo -nodefaultlib $(LINK_DBG) \
diff --git a/win32/config.vc b/win32/config.vc
index a15b926..bc90fd8 100644
--- a/win32/config.vc
+++ b/win32/config.vc
@@ -449,7 +449,7 @@ d_socklen_t='undef'
 d_sockpair='undef'
 d_socks5_init='undef'
 d_sprintf_returns_strlen='define'
-d_sqrtl='undef'
+d_sqrtl='define'
 d_srand48_r='undef'
 d_srandom_r='undef'
 d_sresgproto='undef'
@@ -828,16 +828,16 @@ nm_opt=''
 nm_so_opt=''
 nonxs_ext='Errno'
 nroff=''
-nvEUformat='"E"'
-nvFUformat='"F"'
-nvGUformat='"G"'
+nvEUformat='"LE"'
+nvFUformat='"LF"'
+nvGUformat='"LG"'
 nv_overflows_integers_at='256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0'
 nv_preserves_uv_bits='32'
-nveformat='"e"'
-nvfformat='"f"'
-nvgformat='"g"'
-nvsize='8'
-nvtype='double'
+nveformat='"Le"'
+nvfformat='"Lf"'
+nvgformat='"Lg"'
+nvsize='12'
+nvtype='long double'
 o_nonblock='O_NONBLOCK'
 obj_ext='.obj'
 old_pthread_create_joinable=''
diff --git a/win32/config_H.vc b/win32/config_H.vc
index f55a6d2..7f612f3 100644
--- a/win32/config_H.vc
+++ b/win32/config_H.vc
@@ -1930,9 +1930,9 @@
  *	C preprocessor can make decisions based on it.  It is only
  *	defined if the system supports long doubles.
  */
-#define HAS_LONG_DOUBLE		/**/
+/*#define HAS_LONG_DOUBLE		/**/
 #ifdef HAS_LONG_DOUBLE
-#define LONG_DOUBLESIZE 8		/**/
+#define LONG_DOUBLESIZE 16		/**/
 #endif
 
 /* HAS_LONG_LONG:
@@ -3558,7 +3558,7 @@
  *	available to break a long double floating-point number into
  *	a normalized fraction and an integral power of 2.
  */
-/*#define HAS_FREXPL		/ **/
+#define HAS_FREXPL
 
 /* HAS_STRUCT_FS_DATA:
  *	This symbol, if defined, indicates that the struct fs_data
@@ -3780,8 +3780,8 @@
  *	and 1.150000.  The bug has been seen in certain versions of glibc,
  *	release 2.2.2 is known to be okay.
  */
-/*#define HAS_MODFL		/ **/
-/*#define HAS_MODFL_PROTO		/ **/
+#define HAS_MODFL
+#define HAS_MODFL_PROTO
 /*#define HAS_MODFL_POW32_BUG		/ **/
 
 /* HAS_MPROTECT:
@@ -3954,7 +3954,7 @@
  *	This symbol, if defined, indicates that the sqrtl routine is
  *	available to do long double square roots.
  */
-/*#define HAS_SQRTL		/ **/
+#define HAS_SQRTL		/ **/
 
 /* HAS_SETRESGID_PROTO:
  *	This symbol, if defined, indicates that the system provides
@@ -4361,10 +4361,10 @@
  *	This symbol, if defined, contains the string used by stdio to
  *	format long doubles (format 'f') for input.
  */
-/*#define PERL_PRIfldbl	"f"	/ **/
-/*#define PERL_PRIgldbl	"g"	/ **/
-/*#define PERL_PRIeldbl	"e"	/ **/
-/*#define PERL_SCNfldbl	"f"	/ **/
+#define PERL_PRIfldbl	"f"
+#define PERL_PRIgldbl	"g"
+#define PERL_PRIeldbl	"e"
+#define PERL_SCNfldbl	"f"
 
 /* PERL_MAD:
  *	This symbol, if defined, indicates that the Misc Attribution
@@ -4479,7 +4479,7 @@
 #define	I64TYPE		__int64	/**/
 #define	U64TYPE		unsigned __int64	/**/
 #endif
-#define	NVTYPE		double		/**/
+#define	NVTYPE		long double		/**/
 #define	IVSIZE		4		/**/
 #define	UVSIZE		4		/**/
 #define	I8SIZE		1		/**/
@@ -4492,7 +4492,7 @@
 #define	I64SIZE		8	/**/
 #define	U64SIZE		8	/**/
 #endif
-#define	NVSIZE		8		/**/
+#define	NVSIZE		12		/**/
 #define	NV_PRESERVES_UV
 #define	NV_PRESERVES_UV_BITS	32
 #define	NV_OVERFLOWS_INTEGERS_AT	256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0
@@ -4548,9 +4548,9 @@
 #define	UVof		"lo"		/**/
 #define	UVxf		"lx"		/**/
 #define	UVXf		"lX"		/**/
-#define	NVef		"e"		/**/
-#define	NVff		"f"		/**/
-#define	NVgf		"g"		/**/
+#define	NVef		"Le"		/**/
+#define	NVff		"Lf"		/**/
+#define	NVgf		"Lg"		/**/
 
 /* SELECT_MIN_BITS:
  *	This symbol holds the minimum number of bits operated by select.
-- 
1.8.0.msysgit.0

@p5pRT
Copy link
Author

p5pRT commented Nov 4, 2014

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Nov 4, 2014

From @bulk88

On Mon Nov 03 00​:55​:36 2014, shay wrote​:

The attached patch attempts to add optional GCC-only support for using
long doubles on Win32, but doesn't quite work and I can't figure out
why not. When building with the command "dmake USE_LONG_DOUBLE=define"
we get a miniperl.exe created, but when it is used to run the command
"..\miniperl.exe -I..\lib -f ..\write_buildcustomize.pl .." it fails
like this​:

Invalid version format (negative version number) at lib/vars.pm line
3.
BEGIN failed--compilation aborted at lib/vars.pm line 3.
Compilation failed in require at dist/PathTools/lib/File/Spec.pm line
4.
BEGIN failed--compilation aborted at dist/PathTools/lib/File/Spec.pm
line 4.
Compilation failed in require at
dist/PathTools/lib/File/Spec/Functions.pm line 3.
BEGIN failed--compilation aborted at
dist/PathTools/lib/File/Spec/Functions.pm line 3.
Compilation failed in require at ..\write_buildcustomize.pl line 49.
dmake​: Error code 255, while making '..\lib\buildcustomize.pl'

This "Invalid version format" error is typical of messing up the
floating point routines (stringify/numify), but I haven't figured out
exactly what the problem is yet. I'm recording what I've got so far in
this ticket so that it doesn't get lost.

I ran into that problem when i tried making a Intel C long dobule build. On Visual C, long double is type defed to double. %lf passed to MS CRT is 8 bytes long, but ICC and I assume GCC, say %lf is 12 bytes long. In MS CRT va_arg function/macro, will adjust va_list ptr by 8 bytes for %lf, same as for %f. All further args are gibberish too. Mingw includes its own copies of printf and friends for static linking so long doubles work even though the binary links to msvcrt.dll. I tried using them in object code form for the ICC build but got bogged down trying to separate those printf functions from all the other static link code in mingw's default .o files that get linked (mingw's equivalent to msvcrt.lib, which contains more than just thunks to msvcrt.dll/msvcrt*0.dll).

Visual C for Win16 and MS C for DOS did do 12 byte long doubles. In the Win16 to Win32 transition MS dropped 12 byte long doubles. IDK why. It is sad that MS CRT's source code contains provisions for long doubles in the printf src code. The long double option is just not compiled in (it really can't be on VC, since without compiler support for 80 bit floats, you will be writing everything in inline assembly for VC and long double is a typedef to char[12] array).

I've attached a patch on how far I got with LD on ICC for reference.

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Nov 4, 2014

From @bulk88

0001-icc-longdouble-wip.patch
From 6d149aa0e5feff84216d4da035c7f1b2278e81bc Mon Sep 17 00:00:00 2001
From: Daniel Dragan <bulk88@hotmail.com>
Date: Thu, 9 Jan 2014 03:10:40 -0500
Subject: [PATCH] icc longdouble wip

---
 generate_uudmap.c |  2 ++
 perl.h            | 12 ++++++++++++
 uconfig.h         |  8 ++++----
 util.c            |  9 +++++++--
 win32/Makefile    | 10 +++++-----
 win32/config.vc   | 18 +++++++++---------
 win32/config_H.vc | 30 +++++++++++++++---------------
 7 files changed, 54 insertions(+), 35 deletions(-)

diff --git a/generate_uudmap.c b/generate_uudmap.c
index b6307c0..b72f374 100644
--- a/generate_uudmap.c
+++ b/generate_uudmap.c
@@ -108,6 +108,8 @@ int main(int argc, char **argv) {
   int bits;
   struct mg_data_raw_t *p = mg_data_raw;
 
+    fprintf(stderr, "sizeof ld %d\n", sizeof(long double));
+
   if (argc < 4 || argv[1][0] == '\0' || argv[2][0] == '\0'
       || argv[3][0] == '\0') {
     fprintf(stderr, "Usage: %s uudemap.h bitcount.h mg_data.h\n", argv[0]);
diff --git a/perl.h b/perl.h
index b6e0c3e..6c7d5bd 100644
--- a/perl.h
+++ b/perl.h
@@ -1671,6 +1671,7 @@ typedef UVTYPE UV;
 #  endif
 #  if !(defined(HAS_LONG_DOUBLE) && (LONG_DOUBLESIZE > DOUBLESIZE))
 #     undef USE_LONG_DOUBLE /* Ouch! */
+      #error undefed ULD
 #  endif
 #endif
 
@@ -1763,10 +1764,15 @@ typedef NVTYPE NV;
 #   include <ieeefp.h>
 #endif
 
+#ifndef USE_LONG_DOUBLE
+#error no LD
+#endif
+
 #ifdef USE_LONG_DOUBLE
 #   ifdef I_SUNMATH
 #       include <sunmath.h>
 #   endif
+#   include <mathimf.h>
 #   define NV_DIG LDBL_DIG
 #   ifdef LDBL_MANT_DIG
 #       define NV_MANT_DIG LDBL_MANT_DIG
@@ -1798,6 +1804,7 @@ typedef NVTYPE NV;
 #           endif
 #       endif
 #   endif
+
 #   ifdef HAS_SQRTL
 #       define Perl_cos cosl
 #       define Perl_sin sinl
@@ -1843,6 +1850,7 @@ EXTERN_C long double modfl(long double, long double *);
 #       endif
 #   endif
 #else
+#error die
 #   define NV_DIG DBL_DIG
 #   ifdef DBL_MANT_DIG
 #       define NV_MANT_DIG DBL_MANT_DIG
@@ -5833,6 +5841,10 @@ extern void moncontrol(int);
 
 */
 
+#ifndef HAS_SQRTL
+#error no long
+#endif
+
 #endif /* Include guard */
 
 /*
diff --git a/uconfig.h b/uconfig.h
index 8e728ab..e29fabd 100644
--- a/uconfig.h
+++ b/uconfig.h
@@ -4361,10 +4361,10 @@
  *	This symbol, if defined, contains the string used by stdio to
  *	format long doubles (format 'f') for input.
  */
-/*#define PERL_PRIfldbl	"llf"	/ **/
-/*#define PERL_PRIgldbl	"llg"	/ **/
-/*#define PERL_PRIeldbl	"lle"	/ **/
-/*#define PERL_SCNfldbl	"llf"	/ **/
+#define PERL_PRIfldbl	"llf"	/ **/
+#define PERL_PRIgldbl	"llg"	/ **/
+#define PERL_PRIeldbl	"lle"	/ **/
+#define PERL_SCNfldbl	"llf"	/ **/
 
 /* PERL_MAD:
  *	This symbol, if defined, indicates that the Misc Attribution
diff --git a/util.c b/util.c
index f308e93..455b7bb 100644
--- a/util.c
+++ b/util.c
@@ -4769,10 +4769,12 @@ Perl_my_snprintf(char *buffer, const Size_t len, const char *format, ...)
 {
     int retval;
     va_list ap;
+    restart:
     PERL_ARGS_ASSERT_MY_SNPRINTF;
     va_start(ap, format);
+    memset(buffer, 0, len);
 #ifdef HAS_VSNPRINTF
-    retval = vsnprintf(buffer, len, format, ap);
+    retval = ___mingw_vsnprintf(buffer, len, format, ap);
 #else
     retval = vsprintf(buffer, format, ap);
 #endif
@@ -4784,8 +4786,11 @@ Perl_my_snprintf(char *buffer, const Size_t len, const char *format, ...)
         ||
         (len > 0 && (Size_t)retval >= len) 
 #endif
-    )
+    ) {
+	DebugBreak();
+	goto restart;
 	Perl_croak_nocontext("panic: my_snprintf buffer overflow");
+    }
     return retval;
 }
 
diff --git a/win32/Makefile b/win32/Makefile
index 885f8ce..2c90bef 100644
--- a/win32/Makefile
+++ b/win32/Makefile
@@ -134,14 +134,14 @@ CCTYPE		= MSVC90
 #
 # If you are using Intel C++ Compiler uncomment this
 #
-#__ICC		= define
+__ICC		= define
 
 #
 # uncomment next line if you want debug version of perl (big,slow)
 # If not enabled, we automatically try to use maximum optimization
 # with all compilers that are known to have a working optimizer.
 #
-#CFG		= Debug
+CFG		= Debug
 
 #
 # uncomment to enable linking with setargv.obj under the Visual C
@@ -443,10 +443,10 @@ LOCDEFS		= -DPERLDLL -DPERL_CORE
 SUBSYS		= console
 CXX_FLAG	= -TP -EHsc
 
-LIBC	= msvcrt.lib
+LIBC	= msvcrtd.lib
 
 !IF  "$(CFG)" == "Debug"
-OPTIMIZE	= -Od -MD -Zi -DDEBUGGING
+OPTIMIZE	= -Od -MDd -Zi -DDEBUGGING
 LINK_DBG	= -debug
 !ELSE
 # -O1 yields smaller code, which turns out to be faster than -O2 on x86 and x64
@@ -517,7 +517,7 @@ LIBBASEFILES    = $(LIBBASEFILES) bufferoverflowU.lib
 LIBFILES	= $(LIBBASEFILES) $(LIBC)
 
 #EXTRACFLAGS	= -nologo -GF -W4 -wd4127 -wd4706
-EXTRACFLAGS	= -nologo -GF -W3
+EXTRACFLAGS	= -nologo -GF -W3 /Qlong-double /Qpc80 -DUSE_LONG_DOUBLE -DHAS_LONG_DOUBLE
 CFLAGS		= $(EXTRACFLAGS) $(INCLUDES) $(DEFINES) $(LOCDEFS) \
 		$(PCHFLAGS) $(OPTIMIZE)
 LINK_FLAGS	= -nologo -nodefaultlib $(LINK_DBG) \
diff --git a/win32/config.vc b/win32/config.vc
index a15b926..bc90fd8 100644
--- a/win32/config.vc
+++ b/win32/config.vc
@@ -449,7 +449,7 @@ d_socklen_t='undef'
 d_sockpair='undef'
 d_socks5_init='undef'
 d_sprintf_returns_strlen='define'
-d_sqrtl='undef'
+d_sqrtl='define'
 d_srand48_r='undef'
 d_srandom_r='undef'
 d_sresgproto='undef'
@@ -828,16 +828,16 @@ nm_opt=''
 nm_so_opt=''
 nonxs_ext='Errno'
 nroff=''
-nvEUformat='"E"'
-nvFUformat='"F"'
-nvGUformat='"G"'
+nvEUformat='"LE"'
+nvFUformat='"LF"'
+nvGUformat='"LG"'
 nv_overflows_integers_at='256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0'
 nv_preserves_uv_bits='32'
-nveformat='"e"'
-nvfformat='"f"'
-nvgformat='"g"'
-nvsize='8'
-nvtype='double'
+nveformat='"Le"'
+nvfformat='"Lf"'
+nvgformat='"Lg"'
+nvsize='12'
+nvtype='long double'
 o_nonblock='O_NONBLOCK'
 obj_ext='.obj'
 old_pthread_create_joinable=''
diff --git a/win32/config_H.vc b/win32/config_H.vc
index f55a6d2..7f612f3 100644
--- a/win32/config_H.vc
+++ b/win32/config_H.vc
@@ -1930,9 +1930,9 @@
  *	C preprocessor can make decisions based on it.  It is only
  *	defined if the system supports long doubles.
  */
-#define HAS_LONG_DOUBLE		/**/
+/*#define HAS_LONG_DOUBLE		/**/
 #ifdef HAS_LONG_DOUBLE
-#define LONG_DOUBLESIZE 8		/**/
+#define LONG_DOUBLESIZE 16		/**/
 #endif
 
 /* HAS_LONG_LONG:
@@ -3558,7 +3558,7 @@
  *	available to break a long double floating-point number into
  *	a normalized fraction and an integral power of 2.
  */
-/*#define HAS_FREXPL		/ **/
+#define HAS_FREXPL
 
 /* HAS_STRUCT_FS_DATA:
  *	This symbol, if defined, indicates that the struct fs_data
@@ -3780,8 +3780,8 @@
  *	and 1.150000.  The bug has been seen in certain versions of glibc,
  *	release 2.2.2 is known to be okay.
  */
-/*#define HAS_MODFL		/ **/
-/*#define HAS_MODFL_PROTO		/ **/
+#define HAS_MODFL
+#define HAS_MODFL_PROTO
 /*#define HAS_MODFL_POW32_BUG		/ **/
 
 /* HAS_MPROTECT:
@@ -3954,7 +3954,7 @@
  *	This symbol, if defined, indicates that the sqrtl routine is
  *	available to do long double square roots.
  */
-/*#define HAS_SQRTL		/ **/
+#define HAS_SQRTL		/ **/
 
 /* HAS_SETRESGID_PROTO:
  *	This symbol, if defined, indicates that the system provides
@@ -4361,10 +4361,10 @@
  *	This symbol, if defined, contains the string used by stdio to
  *	format long doubles (format 'f') for input.
  */
-/*#define PERL_PRIfldbl	"f"	/ **/
-/*#define PERL_PRIgldbl	"g"	/ **/
-/*#define PERL_PRIeldbl	"e"	/ **/
-/*#define PERL_SCNfldbl	"f"	/ **/
+#define PERL_PRIfldbl	"f"
+#define PERL_PRIgldbl	"g"
+#define PERL_PRIeldbl	"e"
+#define PERL_SCNfldbl	"f"
 
 /* PERL_MAD:
  *	This symbol, if defined, indicates that the Misc Attribution
@@ -4479,7 +4479,7 @@
 #define	I64TYPE		__int64	/**/
 #define	U64TYPE		unsigned __int64	/**/
 #endif
-#define	NVTYPE		double		/**/
+#define	NVTYPE		long double		/**/
 #define	IVSIZE		4		/**/
 #define	UVSIZE		4		/**/
 #define	I8SIZE		1		/**/
@@ -4492,7 +4492,7 @@
 #define	I64SIZE		8	/**/
 #define	U64SIZE		8	/**/
 #endif
-#define	NVSIZE		8		/**/
+#define	NVSIZE		12		/**/
 #define	NV_PRESERVES_UV
 #define	NV_PRESERVES_UV_BITS	32
 #define	NV_OVERFLOWS_INTEGERS_AT	256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0
@@ -4548,9 +4548,9 @@
 #define	UVof		"lo"		/**/
 #define	UVxf		"lx"		/**/
 #define	UVXf		"lX"		/**/
-#define	NVef		"e"		/**/
-#define	NVff		"f"		/**/
-#define	NVgf		"g"		/**/
+#define	NVef		"Le"		/**/
+#define	NVff		"Lf"		/**/
+#define	NVgf		"Lg"		/**/
 
 /* SELECT_MIN_BITS:
  *	This symbol holds the minimum number of bits operated by select.
-- 
1.8.0.msysgit.0

@p5pRT
Copy link
Author

p5pRT commented Nov 5, 2014

From @steve-m-hay

On Tue Nov 04 02​:33​:51 2014, bulk88 wrote​:

On Mon Nov 03 00​:55​:36 2014, shay wrote​:

The attached patch attempts to add optional GCC-only support for
using
long doubles on Win32, but doesn't quite work and I can't figure out
why not. When building with the command "dmake
USE_LONG_DOUBLE=define"
we get a miniperl.exe created, but when it is used to run the command
"..\miniperl.exe -I..\lib -f ..\write_buildcustomize.pl .." it fails
like this​:

Invalid version format (negative version number) at lib/vars.pm line
3.
BEGIN failed--compilation aborted at lib/vars.pm line 3.
Compilation failed in require at dist/PathTools/lib/File/Spec.pm line
4.
BEGIN failed--compilation aborted at dist/PathTools/lib/File/Spec.pm
line 4.
Compilation failed in require at
dist/PathTools/lib/File/Spec/Functions.pm line 3.
BEGIN failed--compilation aborted at
dist/PathTools/lib/File/Spec/Functions.pm line 3.
Compilation failed in require at ..\write_buildcustomize.pl line 49.
dmake​: Error code 255, while making '..\lib\buildcustomize.pl'

This "Invalid version format" error is typical of messing up the
floating point routines (stringify/numify), but I haven't figured out
exactly what the problem is yet. I'm recording what I've got so far
in
this ticket so that it doesn't get lost.

I ran into that problem when i tried making a Intel C long dobule
build. On Visual C, long double is type defed to double. %lf passed to
MS CRT is 8 bytes long, but ICC and I assume GCC, say %lf is 12 bytes
long. In MS CRT va_arg function/macro, will adjust va_list ptr by 8
bytes for %lf, same as for %f. All further args are gibberish too.
Mingw includes its own copies of printf and friends for static linking
so long doubles work even though the binary links to msvcrt.dll.

I thought that's what I was using by specifying __USE_MINGW_ANSI_STDIO in the gcc build, so I'm not sure why it didn't work out. Do you you know if there's anything else I need to do with gcc to get their long double support working?

@p5pRT
Copy link
Author

p5pRT commented Nov 5, 2014

From @sisyphus

-----Original Message-----
From​: Steve Hay via RT
Sent​: Wednesday, November 05, 2014 7​:14 PM
To​: OtherRecipients of perl Ticket #123113​:
Cc​: perl5-porters@​perl.org
Subject​: [perl #123113] [PATCH] Add optional GCC-only support for using long
doubles on Win32

Mingw includes its own copies of printf and friends for static linking
so long doubles work even though the binary links to msvcrt.dll.

I thought that's what I was using by specifying __USE_MINGW_ANSI_STDIO in
the gcc build, so I'm not sure why it didn't work out. Do you you know if
there's anything else I need to do with gcc to get their long double
support working?

__USE_MINGW_ANSI_STDIO ought to be defined to a true value. I don't think
it's sufficient to merely define the term.
And you need to define __USE_MINGW_ANSI_STDIO *before* certain (any?)
headers get #included.
Defining __USE_MINGW_ANSI_STDIO to a true value before any headers are
#included has always worked fine for me.

If you're already dong that and it's not working then I don't know what's
going wrong.

Cheers,
Rob

@p5pRT
Copy link
Author

p5pRT commented Nov 5, 2014

From @steve-m-hay

On Wed Nov 05 02​:40​:37 2014, sisyphus wrote​:

-----Original Message-----
From​: Steve Hay via RT
Sent​: Wednesday, November 05, 2014 7​:14 PM
To​: OtherRecipients of perl Ticket #123113​:
Cc​: perl5-porters@​perl.org
Subject​: [perl #123113] [PATCH] Add optional GCC-only support for
using long
doubles on Win32

Mingw includes its own copies of printf and friends for static
linking
so long doubles work even though the binary links to msvcrt.dll.

I thought that's what I was using by specifying
__USE_MINGW_ANSI_STDIO in
the gcc build, so I'm not sure why it didn't work out. Do you you
know if
there's anything else I need to do with gcc to get their long double
support working?

__USE_MINGW_ANSI_STDIO ought to be defined to a true value. I don't
think
it's sufficient to merely define the term.
And you need to define __USE_MINGW_ANSI_STDIO *before* certain (any?)
headers get #included.
Defining __USE_MINGW_ANSI_STDIO to a true value before any headers are
#included has always worked fine for me.

It's defined on the gcc command-line so I don't have the problem of it not being seen until after headers are included.

My patch only specified -D__USE_MINGW_ANSI_STDIO, rather than defining it to a true value, but changing that to -D__USE_MINGW_ANSI_STDIO=1 sadly makes no difference :-/

@p5pRT
Copy link
Author

p5pRT commented Nov 5, 2014

From @bulk88

Make a sv.i with USE_MINGW_ANSI_STDIO and a sv.o. Review the .i and objdump /dumpbin (try both!) the sv.o to see what symbols it is is using. Attach the sv.i and sv.o here and I could also take a look.

@p5pRT
Copy link
Author

p5pRT commented Nov 5, 2014

From @steve-m-hay

Would it be possible for someone on a platform where long doubles actually work to post the config.h files of two builds​: One with long doubles disabled and the other with long doubles enabled, but otherwise identical?

It would be instructive to see the differences between them to see whether I've missed some config settings that need twiddling. (I realize that things will need twiddling differently on Windows than elsewhere, but it might still be helpful.)

@p5pRT
Copy link
Author

p5pRT commented Nov 5, 2014

From [Unknown Contact. See original ticket]

Would it be possible for someone on a platform where long doubles actually work to post the config.h files of two builds​: One with long doubles disabled and the other with long doubles enabled, but otherwise identical?

It would be instructive to see the differences between them to see whether I've missed some config settings that need twiddling. (I realize that things will need twiddling differently on Windows than elsewhere, but it might still be helpful.)

@p5pRT
Copy link
Author

p5pRT commented Nov 5, 2014

From @steve-m-hay

On Wed Nov 05 06​:08​:44 2014, bulk88 wrote​:

Make a sv.i with USE_MINGW_ANSI_STDIO and a sv.o. Review the .i and
objdump /dumpbin (try both!) the sv.o to see what symbols it is is
using. Attach the sv.i and sv.o here and I could also take a look.

I've attached the outputs of​:

gcc -c -I.\include -I. -I.. -I..\lib\CORE -DWIN32 -DPERLDLL -DPERL_CORE -s -O2 -D__USE_MINGW_ANSI_STDIO=1 -fwrapv -DPERL_EXTERNAL_GLOB -DPERL_IS_MINIPERL -omini\sv.o ..\sv.c

gcc -E -I.\include -I. -I.. -I..\lib\CORE -DWIN32 -DPERLDLL -DPERL_CORE -s -O2 -D__USE_MINGW_ANSI_STDIO=1 -fwrapv -DPERL_EXTERNAL_GLOB -DPERL_IS_MINIPERL -omini\sv.i ..\sv.c

objdump -x -s sv.o >sv.objdump

dumpbin /all sv.o >sv.dumpbin

@p5pRT
Copy link
Author

p5pRT commented Nov 5, 2014

From @steve-m-hay

sv.zip

@p5pRT
Copy link
Author

p5pRT commented Nov 5, 2014

From @doughera88

On Wed, Nov 05, 2014 at 06​:10​:23AM -0800, Steve Hay via RT wrote​:

Would it be possible for someone on a platform where long doubles actually work to post the config.h files of two builds​: One with long doubles disabled and the other with long doubles enabled, but otherwise identical?

It would be instructive to see the differences between them to see whether I've missed some config settings that need twiddling. (I realize that things will need twiddling differently on Windows than elsewhere, but it might still be helpful.)

Here are the differences for config.sh for Debian GNU/Linux.

#########################################
First, for the 32-bit x86 platform. (I have deleted the
installation directories and archname stuff. Let me know if you need
them.)

102c101
< d_Gconvert='qgcvt((x),(n),(b))'


d_Gconvert='gcvt((x),(n),(b))'
772c771
878,881c877,880
< nvEUformat='"LE"'
< nvFUformat='"LF"'
< nvGUformat='"LG"'
< nv_overflows_integers_at='256.0*256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0*2.0*2.0*2.0'


nvEUformat='"E"'
nvFUformat='"F"'
nvGUformat='"G"'
nv_overflows_integers_at='256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0'
883,887c882,886
< nveformat='"Le"'
< nvfformat='"Lf"'
< nvgformat='"Lg"'
< nvsize='12'
< nvtype='long double'


nveformat='"e"'
nvfformat='"f"'
nvgformat='"g"'
nvsize='8'
nvtype='double'
1083c1082
< uselongdouble='define'


uselongdouble='undef'

#########################################
Next, for the 64-bit x86_64 platform​:

39c40
< alignbytes='8'


alignbytes='16'
101c102
< d_Gconvert='gcvt((x),(n),(b))'


d_Gconvert='qgcvt((x),(n),(b))'
376,377c377,378
< d_nv_preserves_uv='undef'
< d_nv_zero_is_allbits_zero='define'


d_nv_preserves_uv='define'
d_nv_zero_is_allbits_zero='undef'
877,886c878,887
< nvEUformat='"E"'
< nvFUformat='"F"'
< nvGUformat='"G"'
< nv_overflows_integers_at='256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0'
< nv_preserves_uv_bits='53'
< nveformat='"e"'
< nvfformat='"f"'
< nvgformat='"g"'
< nvsize='8'
< nvtype='double'


nvEUformat='"LE"'
nvFUformat='"LF"'
nvGUformat='"LG"'
nv_overflows_integers_at='256.0*256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0*2.0*2.0*2.0'
nv_preserves_uv_bits='64'
nveformat='"Le"'
nvfformat='"Lf"'
nvgformat='"Lg"'
nvsize='16'
nvtype='long double'
1082c1083
< uselongdouble='undef'


uselongdouble='define'

Hope this helps,

--
  Andy Dougherty doughera@​lafayette.edu

@p5pRT
Copy link
Author

p5pRT commented Nov 5, 2014

From @bingos

On Wed, Nov 05, 2014 at 06​:10​:23AM -0800, Steve Hay via RT wrote​:

Would it be possible for someone on a platform where long doubles actually work to post the config.h files of two builds​: One with long doubles disabled and the other with long doubles enabled, but otherwise identical?

It would be instructive to see the differences between them to see whether I've missed some config settings that need twiddling. (I realize that things will need twiddling differently on Windows than elsewhere, but it might still be helpful.)

http​://cpanidx.org/heh/longdouble/

FreeBSD and Linux config.h files with and without -Duselongdouble (with longdouble being -ld-)

Cheers,

--
Chris Williams
aka BinGOs
PGP ID 0x4658671F
http​://www.gumbynet.org.uk

@p5pRT
Copy link
Author

p5pRT commented Nov 5, 2014

From @sisyphus

-----Original Message-----
From​: Steve Hay via RT
Sent​: Thursday, November 06, 2014 12​:57 AM
To​: OtherRecipients of perl Ticket #123113​:
Cc​: perl5-porters@​perl.org
Subject​: [perl #123113] [PATCH] Add optional GCC-only support for using long
doubles on Win32

__USE_MINGW_ANSI_STDIO ought to be defined to a true value. I don't
think
it's sufficient to merely define the term.
And you need to define __USE_MINGW_ANSI_STDIO *before* certain (any?)
headers get #included.
Defining __USE_MINGW_ANSI_STDIO to a true value before any headers are
#included has always worked fine for me.

It's defined on the gcc command-line so I don't have the problem of it not
being seen until after headers are included.

My patch only specified -D__USE_MINGW_ANSI_STDIO, rather than defining it
to a true value, but changing that to -D__USE_MINGW_ANSI_STDIO=1 sadly
makes no difference :-/

On checking I find that -D__USE_MINGW_ANSI_STDIO on the command line is
indeed sufficient (as you say).
The "-D__USE_MINGW_ANSI_STDIO" automatically assigns a default value of 1.

Cheers,
Rob

@p5pRT
Copy link
Author

p5pRT commented Nov 6, 2014

From @steve-m-hay

On Wed Nov 05 09​:39​:53 2014, chris@​bingosnet.co.uk wrote​:

On Wed, Nov 05, 2014 at 06​:10​:23AM -0800, Steve Hay via RT wrote​:

Would it be possible for someone on a platform where long doubles
actually work to post the config.h files of two builds​: One with long
doubles disabled and the other with long doubles enabled, but
otherwise identical?

It would be instructive to see the differences between them to see
whether I've missed some config settings that need twiddling. (I
realize that things will need twiddling differently on Windows than
elsewhere, but it might still be helpful.)

http​://cpanidx.org/heh/longdouble/

FreeBSD and Linux config.h files with and without -Duselongdouble
(with longdouble being -ld-)

Fantastic! Thanks, Chris. That's led me straight to the problem​: I'd forgotten to adjust NVef/NVff/NVgf (and also Gconvert). With them adjusted suitably I now have a working miniperl.exe. Hopefully perl.exe will work too and I'll commit this soon :-)

@p5pRT
Copy link
Author

p5pRT commented Nov 6, 2014

From @steve-m-hay

On Thu Nov 06 00​:25​:57 2014, shay wrote​:

On Wed Nov 05 09​:39​:53 2014, chris@​bingosnet.co.uk wrote​:

On Wed, Nov 05, 2014 at 06​:10​:23AM -0800, Steve Hay via RT wrote​:

Would it be possible for someone on a platform where long doubles
actually work to post the config.h files of two builds​: One with
long
doubles disabled and the other with long doubles enabled, but
otherwise identical?

It would be instructive to see the differences between them to see
whether I've missed some config settings that need twiddling. (I
realize that things will need twiddling differently on Windows than
elsewhere, but it might still be helpful.)

http​://cpanidx.org/heh/longdouble/

FreeBSD and Linux config.h files with and without -Duselongdouble
(with longdouble being -ld-)

Fantastic! Thanks, Chris. That's led me straight to the problem​: I'd
forgotten to adjust NVef/NVff/NVgf (and also Gconvert). With them
adjusted suitably I now have a working miniperl.exe. Hopefully
perl.exe will work too and I'll commit this soon :-)

This is now committed with commit 890b508.

It builds and passes all tests except for two pack tests​:

C​:\Dev\Git\perl\t>..\perl harness op/pack.t
[18​:29​:13] op/pack.t .. 7086/14704 # Failed test 13177 - at op/pack.t line 1411
# got "173 1.28347651700000004e-045 42 215 173 1.28347651700000004e-045 42 215"
# expected "173 1.283476517e-045 42 215 173 1.283476517e-045 42 215"
# Failed test 13180 - at op/pack.t line 1424
# got "173 1.28347651700000004e-045 42 215"
# expected "173 1.283476517e-045 42 215"
[18​:29​:13] op/pack.t .. Failed 2/14704 subtests
  (less 269 skipped subtests​: 14433 okay)
[18​:29​:14]

Test Summary Report


op/pack.t (Wstat​: 0 Tests​: 14704 Failed​: 2)
  Failed tests​: 13177, 13180
Files=1, Tests=14704, 1 wallclock secs ( 0.86 usr + 0.00 sys = 0.86 CPU)
Result​: FAIL

Any ideas as to what's gone wrong there?

There is two other things​: Looking at the config.h diffs between normal and long-double builds on FreeBSD and Linux I noticed that they both #undef NV_ZERO_IS_ALLBITS_ZERO for long-double builds. I haven't done that in this MinGW/gcc change so far. Do I need to? (I tried it, but it didn't fix the above test failures.)

FreeBSD and Linux also changed MEM_ALIGNBYTES from 8 to 16, which I also haven't done here, but then they do have NVSIZE 16, whereas MinGW/gcc is 12. Do I need to do anything with MEM_ALIGNBYTES?

Otherwise, I think I covered everything.

(This ticket should probably be left open, with the title suitably changed, for the unfinished ICC work also recorded here.)

@p5pRT
Copy link
Author

p5pRT commented Nov 7, 2014

From @sisyphus

-----Original Message-----
From​: Steve Hay via RT
Sent​: Friday, November 07, 2014 5​:20 AM
To​: OtherRecipients of perl Ticket #123113​:
Cc​: perl5-porters@​perl.org
Subject​: [perl #123113] [PATCH] Add optional GCC-only support for using long
doubles on Win32

op/pack.t (Wstat​: 0 Tests​: 14704 Failed​: 2)
Failed tests​: 13177, 13180
Files=1, Tests=14704, 1 wallclock secs ( 0.86 usr + 0.00 sys = 0.86
CPU)
Result​: FAIL

The same two tests fail (in the same way) for me.

I don't understand those tests.
I take it that the value 1.283476517e-045 is being packed in some way such
that it unpacks to 1.28347651700000004e-045.

Is there some simpler code that can reproduce this anomalous result ?
Anything else I try with this perl simply confirms that 1.283476517e-045
equates to 1.28347651700000000e-045, not 1.28347651700000004e-045.

I'd like to thank you for taking this on Steve - it's something long
overdue, IMO.
My only reservation about the importance of providing "long double"
capability is my notion that if 53 bits of precision is insufficient, then
it's likely that 64 bits of precision is also insufficient.

You can take that "reservation" as a thinly veiled suggestion that it would
be a good idea to extend __float128 capability (recently added by Jarkko,
utilising the quadmath library) to windows, too ;-)
Recent mingw.org and mingw-w64 compilers ship with quadmath - so the
potential for a Windows NV with 113 bits of precision is a definite
possibility. (For example, Math​::Float128 builds fine on Windows so long as
the quadmath library is found.)
Unfortunately, the mingw-w64 compilers that ship with current and recent
Strawberry Perls have a bug in the exponential function (expq) which crashes
at runtime. My understanding is that this bug has been fixed in 4.9.x
compilers (for some value of x) and later - in the meantime I've been using
powq(M_Eq, x) instead of expq(x).
Other than that, mingw's libquadmath should be fine for __float128 support
on Windows.

Anyway .... one step at a time; and I expect you're a bit weary after having
worked your way through the task of providing "long double" capability.
Thanks again for doing that !!

Cheers,
Rob

@p5pRT
Copy link
Author

p5pRT commented Nov 21, 2014

From @sisyphus

-----Original Message-----
From​: sisyphus1@​optusnet.com.au
Sent​: Friday, November 07, 2014 12​:11 PM
To​: perlbug-followup@​perl.org
Cc​: perl5-porters@​perl.org
Subject​: Re​: [perl #123113] [PATCH] Add optional GCC-only support for using
long doubles on Win32

-----Original Message-----
From​: Steve Hay via RT
Sent​: Friday, November 07, 2014 5​:20 AM

op/pack.t (Wstat​: 0 Tests​: 14704 Failed​: 2)
Failed tests​: 13177, 13180
Files=1, Tests=14704, 1 wallclock secs ( 0.86 usr + 0.00 sys = 0.86
CPU)
Result​: FAIL

The same two tests fail (in the same way) for me.

The 64-bit build is worse. (Perl -V is attached.)

op/pack.t (Wstat​: 0
Tests​: 14704 Failed​: 418)
  Failed tests​: 7012, 7014, 7016, 7018, 7022, 7024, 7026
  7028, 7030, 7032, 7034, 7036, 7038, 7040
  7042, 7044, 7046, 7048, 7050, 7052, 7054
  7056, 7058, 7060, 7062, 7064, 7066, 7068
  7070, 7072, 7074, 7076, 7078, 7080, 7082
  7084, 7086, 7088, 7090, 7092, 7094, 7096
  7098, 7100, 7102, 7104, 7106, 7108, 7110
  7112, 7114, 7116, 7118, 8308, 8310, 8312
  8314, 8318, 8320, 8322, 8324, 8326, 8328
  8330, 8332, 8334, 8336, 8338, 8340, 8342
  8344, 8346, 8348, 8350, 8352, 8354, 8356
  8358, 8360, 8362, 8364, 8366, 8368, 8370
  8372, 8374, 8376, 8378, 8380, 8382, 8384
  8386, 8388, 8390, 8392, 8394, 8396, 8398
  8400, 8402, 8404, 8406, 8408, 8410, 8412
  8414, 10360, 10362, 10364, 10366, 10370
  10372, 10374, 10376, 10378, 10380, 10382
  10384, 10386, 10388, 10390, 10392, 10394
  10396, 10398, 10400, 10402, 10404, 10406
  10408, 10410, 10412, 10414, 10416, 10418
  10420, 10422, 10424, 10426, 10428, 10430
  10432, 10434, 10436, 10438, 10440, 10442
  10444, 10446, 10448, 10450, 10452, 10454
  10456, 10458, 10460, 10462, 10464, 10466
  10468, 10470, 10472, 10474, 10478, 10480
  10482, 10484, 10486, 10488, 10490, 10492
  10494, 10496, 10498, 10500, 10502, 10504
  10506, 10508, 10510, 10512, 10514, 10516
  10518, 10520, 10522, 10524, 10526, 10528
  10530, 10532, 10534, 10536, 10538, 10540
  10542, 10544, 10546, 10548, 10550, 10552
  10554, 10556, 10558, 10560, 10562, 10564
  10566, 10568, 10570, 10572, 10574, 12952
  12954, 12956, 12958, 12962, 12964, 12966
  12968, 12970, 12972, 12974, 12976, 12978
  12980, 12982, 12984, 12986, 12988, 12990
  12992, 12994, 12996, 12998, 13000, 13002
  13004, 13006, 13008, 13010, 13012, 13014
  13016, 13018, 13020, 13022, 13024, 13026
  13028, 13030, 13032, 13034, 13036, 13038
  13040, 13042, 13044, 13046, 13048, 13050
  13052, 13054, 13056, 13058, 13060, 13062
  13064, 13066, 13070, 13072, 13074, 13076
  13078, 13080, 13082, 13084, 13086, 13088
  13090, 13092, 13094, 13096, 13098, 13100
  13102, 13104, 13106, 13108, 13110, 13112
  13114, 13116, 13118, 13120, 13122, 13124
  13126, 13128, 13130, 13132, 13134, 13136
  13138, 13140, 13142, 13144, 13146, 13148
  13150, 13152, 13154, 13156, 13158, 13160
  13162, 13164, 13166, 13177, 13180, 13183
  13526, 13529, 13532, 13535, 13538, 13541
  13544, 13547, 13550, 13553, 13556, 13559
  13562, 13565, 13568, 13581, 13584, 13587
  13590, 13593, 13596, 13599, 13602, 13605
  13608, 13611, 13614, 13617, 13620, 13623
  13636, 13639, 13642, 13645, 13648, 13651
  13654, 13657, 13660, 13663, 13666, 13669
  13672, 13675, 13678-13679, 13692, 13695
  13698, 13701, 13704, 13707, 13710, 13713
  13716, 13719, 13722, 13725, 13728, 13731
  13734, 13747, 13750, 13753, 13756, 13759
  13762, 13765, 13768, 13771, 13774, 13777
  13780, 13783, 13786, 13789, 13802, 13805
  13808, 13811, 13814, 13817, 13820, 13823
  13826, 13829, 13832, 13835, 13838, 13841
  13844, 13997, 14001, 14003, 14005, 14009
  14011
porting/pod_rules.t (Wstat​: 0
Tests​: 7 Failed​: 1)

And that test script also sometimes crashes just prior to exit.

I also get a crash in​:
C​:\_64\comp\perl-5.21.6>perl -Ilib cpan/Test-Simple/t/Legacy/subtest/fork.t
1..1
# Subtest​: fork within subtest
  1..2
[crash - perl.exe has stopped working]

I'm using the gcc that shipped with x64 StrawberryPerl-5.20.0​:
gcc version 4.8.2 (x86_64-posix-sjlj, built by strawberryperl.com project)

Steve, are you able to verify that this is not just me doing something wrong
?

I also built a 32-bit 5.21.6 using the gcc compiler that shipped with x86
StrawberryPerl-5.20.0​:
gcc version 4.8.2 (i686-posix-sjlj, built by strawberryperl.com project)
No problems with it that we didn't already know about.

Cheers,
Rob

@p5pRT
Copy link
Author

p5pRT commented Nov 21, 2014

From @sisyphus

Summary of my perl5 (revision 5 version 21 subversion 6) configuration​:

  Platform​:
  osname=MSWin32, osvers=6.1, archname=MSWin32-x64-multi-thread
  uname=''
  config_args='undef'
  hint=recommended, useposix=true, d_sigaction=undef
  useithreads=define, usemultiplicity=define
  use64bitint=define, use64bitall=undef, uselongdouble=define
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='gcc', ccflags
' -s -O2 -DWIN32 -DWIN64 -DCONSERVATIVE -DPERL_TEXTMODE_SCRIPTS -DPERL_IMPL
ICIT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO -D__USE_MINGW_ANSI_STDIO -fwra
pv -fno-strict-aliasing -mms-bitfields',
  optimize='-s -O2',
  cppflags='-DWIN32'
  ccversion='', gccversion='4.8.2', gccosandvers=''
  intsize=4, longsize=4, ptrsize=8, doublesize=8, byteorder=12345678,
doublekind=3
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12,
longdblkind=3
  ivtype='long long', ivsize=8, nvtype='long double', nvsize=12,
Off_t='long long', lseeksize=8
  alignbytes=8, prototype=define
  Linker and Libraries​:
  ld='g++', ldflags
='-s -L"c​:\_64\bleadperl\lib\CORE" -L"C​:\_64\strawberry5.20.0\c\lib"'
  libpth=C​:\_64\strawberry5.20.0\c\lib "C​:\_64\msys_482\1.0\local\lib
C​:\_64\msys_482\1.0\local\ssl\lib"
  libs=-lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladva
pi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwinmm -
lversion -lodbc32 -lodbccp32 -lcomctl32
  perllibs=-lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -l
advapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwin
mm -lversion -lodbc32 -lodbccp32 -lcomctl32
  libc=, so=dll, useshrplib=true, libperl=libperl521.a
  gnulibc_version=''
  Dynamic Linking​:
  dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
  cccdlflags=' ',
lddlflags='-mdll -s -L"c​:\_64\bleadperl\lib\CORE" -L"C​:\_64\strawberry5.20.0
\c\lib"'

Characteristics of this binary (from libperl)​:
  Compile-time options​: HAS_TIMES HAVE_INTERP_INTERN MULTIPLICITY
  PERLIO_LAYERS PERL_DONT_CREATE_GVSV
  PERL_HASH_FUNC_ONE_AT_A_TIME_HARD
  PERL_IMPLICIT_CONTEXT PERL_IMPLICIT_SYS
  PERL_MALLOC_WRAP PERL_NEW_COPY_ON_WRITE
  PERL_PRESERVE_IVUV USE_64_BIT_INT USE_ITHREADS
  USE_LARGE_FILES USE_LOCALE USE_LOCALE_COLLATE
  USE_LOCALE_CTYPE USE_LOCALE_NUMERIC USE_LOCALE_TIME
  USE_LONG_DOUBLE USE_PERLIO USE_PERL_ATOF
  Built under MSWin32
  Compiled at Nov 21 2014 13​:04​:36
  @​INC​:
  C​:/_64/comp/perl-5.21.6/lib
  .

@p5pRT
Copy link
Author

p5pRT commented Nov 21, 2014

From @sisyphus

-----Original Message-----
From​: sisyphus1@​optusnet.com.au
Sent​: Friday, November 21, 2014 4​:58 PM
To​: perlbug-followup@​perl.org
Cc​: perl5-porters@​perl.org
Subject​: Re​: [perl #123113] [PATCH] Add optional GCC-only support for using
long doubles on Win32

The 64-bit build is worse.

Hang on, looks like sizeof(long double) differs between 32-bit and 64-bit
MinGW compilers​:

This script​:

###############################
use warnings;
use Config;
use Inline C => <<'EOC';

void foo() {
printf("%u %u\n", LDBL_DIG, LDBL_MANT_DIG);
printf("%u %u\n", sizeof(long double), sizeof(NV));
}

EOC

foo();
print "$Config{longdblsize} $Config{nvsize}\n";
###############################

on 32-bit ld perl-5.21.6 outputs​:

18 64
12 12
12 12

but on 64-bit ld perl-5.21.6 outputs​:

18 64
16 16
12 12

I don't know how that will affect the way 64-bit perl runs, but it's an
anomaly that should be fixed for the next release anyway.

I wonder why sizeof(long double) differs between 32-bit and 64-bit mingw-w64
compilers ??
(At least now I don't feel so stupid for having asserted a while back that
sizeof(long double) was 16 for mingw compilers. Iit *is* ...... so long as
you look at the right mingw compiler ;-)

Cheers,
Rob

@p5pRT
Copy link
Author

p5pRT commented Nov 21, 2014

From @sisyphus

-----Original Message-----
From​: sisyphus1@​optusnet.com.au

... but it's an anomaly that should be fixed for the next release anyway.

Just to clarify - it's the anomaly (on 64-bit builds) between what %Config
reports and what C's sizeof() function reports that needs to be fixed.

I didn't mean that we should make C's sizeof(long double) report the same
value for both 32-bit and 64-bit compilers ;-)

Cheers,
Rob

@p5pRT
Copy link
Author

p5pRT commented Nov 21, 2014

From @steve-m-hay

On 21 November 2014 07​:34, <sisyphus1@​optusnet.com.au> wrote​:

-----Original Message----- From​: sisyphus1@​optusnet.com.au

... but it's an anomaly that should be fixed for the next release anyway.

Just to clarify - it's the anomaly (on 64-bit builds) between what %Config
reports and what C's sizeof() function reports that needs to be fixed.

I didn't mean that we should make C's sizeof(long double) report the same
value for both 32-bit and 64-bit compilers ;-)

It's more than just an anomaly​: It's the cause of all the extra
(compared to 32-bit) failures in op/pack.t!

Thanks for reporting those test failures; I clearly hadn't got round
to trying a 64-bit long double build myself. (Which is a little
worrying because I thought I had done it,but maybe I only tried
64-bit-int with long doubles...)

And thanks for spotting the longdblsize error. I've just fixed that in
commit 82319b0, and op/pack.t now passes all but two tests in a
64-bit long double build. It fails the same two tests as the 32-bit
long double build, which I sadly still haven't got round to trying to
get to the bottom of.

@p5pRT
Copy link
Author

p5pRT commented Nov 27, 2014

From @sisyphus

Steve, here's another little glitch that I've come across.
On the 32-bit build of 5.21.6​:

C​:\>perl -V​:nvtype
nvtype='long double';

C​:\>perl -V​:nvsize
nvsize='12';

C​:\>perl -MPOSIX -le "$x=POSIX​::strtold('12345.1');"
POSIX​::strtold not implemented on this architecture at -e line 1.

C​:\>

On the 64-bit build of 5.21.6 (where nvsize is set incorrectly) it's the
same message​:

C​:\>perl -V​:nvtype
nvtype='long double';

C​:\>perl -V​:nvsize
nvsize='12';

C​:\>perl -MPOSIX -le "$x=POSIX​::strtold('12345.1');"
POSIX​::strtold not implemented on this architecture at -e line 1.

AFAIK, POSIX​::strtold() should have been implemented for these perls.

Cheers,
Rob

@p5pRT
Copy link
Author

p5pRT commented Nov 27, 2014

From @steve-m-hay

On 27 November 2014 at 03​:46, <sisyphus1@​optusnet.com.au> wrote​:

Steve, here's another little glitch that I've come across.
On the 32-bit build of 5.21.6​:

C​:\>perl -V​:nvtype
nvtype='long double';

C​:\>perl -V​:nvsize
nvsize='12';

C​:\>perl -MPOSIX -le "$x=POSIX​::strtold('12345.1');"
POSIX​::strtold not implemented on this architecture at -e line 1.

C​:\>

On the 64-bit build of 5.21.6 (where nvsize is set incorrectly) it's the
same message​:

C​:\>perl -V​:nvtype
nvtype='long double';

C​:\>perl -V​:nvsize
nvsize='12';

C​:\>perl -MPOSIX -le "$x=POSIX​::strtold('12345.1');"
POSIX​::strtold not implemented on this architecture at -e line 1.

AFAIK, POSIX​::strtold() should have been implemented for these perls.

I think that must be a gremlin lurking in POSIX.pm/xs. I made the
appropriate configuration changes for perl itself, which you can
confirm with​:

perl -V​:d_strtold

Assuming that prints 'define' as it should then it's just POSIX that
needs some work.

@p5pRT
Copy link
Author

p5pRT commented Nov 27, 2014

From @steve-m-hay

On 27 November 2014 at 09​:02, Steve Hay <steve.m.hay@​googlemail.com> wrote​:

On 27 November 2014 at 03​:46, <sisyphus1@​optusnet.com.au> wrote​:

Steve, here's another little glitch that I've come across.
On the 32-bit build of 5.21.6​:

C​:\>perl -V​:nvtype
nvtype='long double';

C​:\>perl -V​:nvsize
nvsize='12';

C​:\>perl -MPOSIX -le "$x=POSIX​::strtold('12345.1');"
POSIX​::strtold not implemented on this architecture at -e line 1.

C​:\>

On the 64-bit build of 5.21.6 (where nvsize is set incorrectly) it's the
same message​:

C​:\>perl -V​:nvtype
nvtype='long double';

C​:\>perl -V​:nvsize
nvsize='12';

C​:\>perl -MPOSIX -le "$x=POSIX​::strtold('12345.1');"
POSIX​::strtold not implemented on this architecture at -e line 1.

AFAIK, POSIX​::strtold() should have been implemented for these perls.

I think that must be a gremlin lurking in POSIX.pm/xs. I made the
appropriate configuration changes for perl itself, which you can
confirm with​:

perl -V​:d_strtold

Assuming that prints 'define' as it should then it's just POSIX that
needs some work.

Does the attached (untested) blind stab in the dark fix it?

@p5pRT
Copy link
Author

p5pRT commented Nov 27, 2014

From @steve-m-hay

0001-Enable-POSIX-strtold-on-Windows-GCC-USE_LONG_DOUBLE-.patch
From cd23470b782536aa82a4f98a6ada0ff9a4cc5004 Mon Sep 17 00:00:00 2001
From: Steve Hay <steve.m.hay@googlemail.com>
Date: Thu, 27 Nov 2014 09:08:56 +0000
Subject: [PATCH] Enable POSIX::strtold() on Windows (GCC) USE_LONG_DOUBLE
 builds

---
 ext/POSIX/POSIX.xs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/ext/POSIX/POSIX.xs b/ext/POSIX/POSIX.xs
index 9d41bf0..39b7f36 100644
--- a/ext/POSIX/POSIX.xs
+++ b/ext/POSIX/POSIX.xs
@@ -1134,7 +1134,9 @@ char *tzname[] = { "" , "" };
 #  define setuid(a)		not_here("setuid")
 #  define setgid(a)		not_here("setgid")
 #endif	/* NETWARE */
+#ifndef USE_LONG_DOUBLE
 #  define strtold(s1,s2)	not_here("strtold")
+#endif  /* USE_LONG_DOUBLE */
 #else
 
 #  ifndef HAS_MKFIFO
-- 
1.8.4.msysgit.0

@p5pRT
Copy link
Author

p5pRT commented Nov 27, 2014

From @demerphq

On 21 November 2014 at 08​:16, <sisyphus1@​optusnet.com.au> wrote​:

-----Original Message----- From​: sisyphus1@​optusnet.com.au
Sent​: Friday, November 21, 2014 4​:58 PM
To​: perlbug-followup@​perl.org
Cc​: perl5-porters@​perl.org
Subject​: Re​: [perl #123113] [PATCH] Add optional GCC-only support for
using long doubles on Win32

The 64-bit build is worse.

Hang on, looks like sizeof(long double) differs between 32-bit and 64-bit
MinGW compilers​:

This script​:

###############################
use warnings;
use Config;
use Inline C => <<'EOC';

void foo() {
printf("%u %u\n", LDBL_DIG, LDBL_MANT_DIG);
printf("%u %u\n", sizeof(long double), sizeof(NV));
}

EOC

foo();
print "$Config{longdblsize} $Config{nvsize}\n";
###############################

on 32-bit ld perl-5.21.6 outputs​:

18 64
12 12
12 12

but on 64-bit ld perl-5.21.6 outputs​:

18 64
16 16
12 12

I don't know how that will affect the way 64-bit perl runs, but it's an
anomaly that should be fixed for the next release anyway.

I wonder why sizeof(long double) differs between 32-bit and 64-bit
mingw-w64 compilers ??

It is not a mingw issue, it is an x86 issue. I dont recall exactly the
details but on x86 it is either an OS setting, or a compiler setting as to
whether a long double is represented as a simple double or if it is
represented as an extended precision 80 bit value. I have a hazy
recollection that Linux and Windows use the extended precision mode, and
FreeBSD derivatives use the plain double representation.

Where the compiler does use the extended precisions floats it store them
differently on 32 and 64 bit architectures. On 32 bit it is stored in 12
bytes (3 x 32 bit words), and in 64 bit builds it is stored in 16 bytes (2
x 64 bit words). Either way the compiler and the CPU only use 10 bytes of
what is stored. (In some contexts this means either representation can
"leak" sensitive data as the compiler does not clear the unused bytes.)

Yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"

@p5pRT
Copy link
Author

p5pRT commented Nov 27, 2014

From @sisyphus

On 27 November 2014 at 09​:02, Steve Hay <steve.m.hay@​googlemail.com> wrote​:

Assuming that prints 'define' as it should then it's just POSIX that
needs some work.

Does the attached (untested) blind stab in the dark fix it?

Yes, that rectifies the problem on the 32-bit. Can't see any reason it
wouldn't also work on the 64-bit build (but I didn't actually check).

Cheers,
Rob

@p5pRT
Copy link
Author

p5pRT commented Nov 27, 2014

From @steve-m-hay

On 27 November 2014 at 11​:27, <sisyphus1@​optusnet.com.au> wrote​:

On 27 November 2014 at 09​:02, Steve Hay <steve.m.hay@​googlemail.com>
wrote​:

Assuming that prints 'define' as it should then it's just POSIX that
needs some work.

Does the attached (untested) blind stab in the dark fix it?

Yes, that rectifies the problem on the 32-bit. Can't see any reason it
wouldn't also work on the 64-bit build (but I didn't actually check).

Thanks for spotting (and testing). Now pushed to blead in commit
d172007.

@p5pRT
Copy link
Author

p5pRT commented Mar 18, 2015

From @jkeenan

On Thu Nov 27 06​:13​:29 2014, shay wrote​:

On 27 November 2014 at 11​:27, <sisyphus1@​optusnet.com.au> wrote​:

On 27 November 2014 at 09​:02, Steve Hay <steve.m.hay@​googlemail.com>
wrote​:

Assuming that prints 'define' as it should then it's just POSIX that
needs some work.

Does the attached (untested) blind stab in the dark fix it?

Yes, that rectifies the problem on the 32-bit. Can't see any reason it
wouldn't also work on the 64-bit build (but I didn't actually check).

Thanks for spotting (and testing). Now pushed to blead in commit
d172007.

Is this ticket closable?

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Mar 18, 2015

From @steve-m-hay

On Tue Mar 17 18​:49​:44 2015, jkeenan wrote​:

On Thu Nov 27 06​:13​:29 2014, shay wrote​:

On 27 November 2014 at 11​:27, <sisyphus1@​optusnet.com.au> wrote​:

On 27 November 2014 at 09​:02, Steve Hay <steve.m.hay@​googlemail.com>
wrote​:

Assuming that prints 'define' as it should then it's just POSIX that
needs some work.

Does the attached (untested) blind stab in the dark fix it?

Yes, that rectifies the problem on the 32-bit. Can't see any reason it
wouldn't also work on the 64-bit build (but I didn't actually check).

Thanks for spotting (and testing). Now pushed to blead in commit
d172007.

Is this ticket closable?

Yes, except that I wrote in https://rt-archive.perl.org/perl5/Ticket/Display.html?id=123113#txn-1317316 "This ticket should probably be left open, with the title suitably changed, for the unfinished ICC work also recorded here." But maybe it would be better to raise a new ticket for that separate work?

@p5pRT
Copy link
Author

p5pRT commented Feb 26, 2017

From @jkeenan

On Wed, 18 Mar 2015 08​:39​:53 GMT, shay wrote​:

On Tue Mar 17 18​:49​:44 2015, jkeenan wrote​:

On Thu Nov 27 06​:13​:29 2014, shay wrote​:

On 27 November 2014 at 11​:27, <sisyphus1@​optusnet.com.au> wrote​:

On 27 November 2014 at 09​:02, Steve Hay
<steve.m.hay@​googlemail.com>
wrote​:

Assuming that prints 'define' as it should then it's just POSIX
that
needs some work.

Does the attached (untested) blind stab in the dark fix it?

Yes, that rectifies the problem on the 32-bit. Can't see any
reason it
wouldn't also work on the 64-bit build (but I didn't actually
check).

Thanks for spotting (and testing). Now pushed to blead in commit
d172007.

Is this ticket closable?

Yes, except that I wrote in
https://rt-archive.perl.org/perl5/Ticket/Display.html?id=123113#txn-1317316 "This
ticket should probably be left open, with the title suitably changed,
for the unfinished ICC work also recorded here." But maybe it would be
better to raise a new ticket for that separate work?

Could you create that ICC-specific ticket? (We could then close this one, AFAICT.)

Thank you very much.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Nov 21, 2017

From @steve-m-hay

On Sun, 26 Feb 2017 15​:29​:43 -0800, jkeenan wrote​:

On Wed, 18 Mar 2015 08​:39​:53 GMT, shay wrote​:

On Tue Mar 17 18​:49​:44 2015, jkeenan wrote​:

On Thu Nov 27 06​:13​:29 2014, shay wrote​:

On 27 November 2014 at 11​:27, <sisyphus1@​optusnet.com.au> wrote​:

On 27 November 2014 at 09​:02, Steve Hay
<steve.m.hay@​googlemail.com>
wrote​:

Assuming that prints 'define' as it should then it's just
POSIX
that
needs some work.

Does the attached (untested) blind stab in the dark fix it?

Yes, that rectifies the problem on the 32-bit. Can't see any
reason it
wouldn't also work on the 64-bit build (but I didn't actually
check).

Thanks for spotting (and testing). Now pushed to blead in commit
d172007.

Is this ticket closable?

Yes, except that I wrote in
https://rt-archive.perl.org/perl5/Ticket/Display.html?id=123113#txn-1317316 "This
ticket should probably be left open, with the title suitably changed,
for the unfinished ICC work also recorded here." But maybe it would
be
better to raise a new ticket for that separate work?

Could you create that ICC-specific ticket? (We could then close this
one, AFAICT.)

Thank you very much.

I've finally got round to doing this in #132478 (with the two test failures also now recorded separately in #132479).

Closing this ticket now.

@p5pRT
Copy link
Author

p5pRT commented Nov 21, 2017

@steve-m-hay - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant