In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/5124ce1ebfdf638521d2a0e17ddc9f6c56faa4ff?hp=ee30e416ad055ff6c8dae1391480d560139666ca>
- Log ----------------------------------------------------------------- commit 5124ce1ebfdf638521d2a0e17ddc9f6c56faa4ff Author: Jarkko Hietaniemi <[email protected]> Date: Mon Nov 3 21:32:19 2014 -0500 S_hextract for mixed endian doubles. M sv.c commit f8d924aed543b0e974ba0edec10a6d60b7ee7d81 Author: Jarkko Hietaniemi <[email protected]> Date: Mon Nov 3 21:17:40 2014 -0500 Add scan for ARM mixed-endian doubles. (Working in theory... no hardware.) M Configure M Porting/Glossary M config_h.SH commit 17059a03f667b30230374a63a775d805949955fe Author: Jarkko Hietaniemi <[email protected]> Date: Mon Nov 3 21:08:48 2014 -0500 8e581bbf covered up this bug. M Configure ----------------------------------------------------------------------- Summary of changes: Configure | 22 ++++++++++++++++++---- Porting/Glossary | 2 ++ config_h.SH | 4 ++++ sv.c | 26 ++++++++++++++++++++++++-- 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/Configure b/Configure index 9494ab1..9bd6f18 100755 --- a/Configure +++ b/Configure @@ -6813,24 +6813,38 @@ int main() { } #endif #if DOUBLESIZE == 8 - if (b[0] == 0x9A && b[7] == 0xBD) { + if (b[0] == 0x9A && b[7] == 0xBF) { /* IEEE 754 64-bit little-endian */ printf("3\n"); exit(0); } - if (b[0] == 0x9A && b[7] == 0xCD) { + if (b[0] == 0xBF && b[7] == 0x9A) { /* IEEE 754 64-bit big-endian */ printf("4\n"); exit(0); } + if (b[0] == 0x99 && b[3] == 0xBF && b[4] == 0x9A && b[7] == 0x99) { + /* ARM mixed endian: two little-endian 32-bit floats, in big endian order: + * 4 5 6 7 0 1 2 3 (MSB = 7, LSB = 0) + * 99 99 b9 bf 9a 99 99 99 */ + printf("7\n"); + exit(0); + } + if (b[0] == 0x99 && b[3] == 0x9A && b[4] == 0xBF && b[7] == 0x99) { + /* The opposite of case 7, mixed endian: two big-endian 32-bit floats, + * in little endian order: 3 2 1 0 7 6 5 4 (MSB = 7, LSB = 0) + * 99 99 99 9a bf b9 99 99 */ + printf("8\n"); + exit(0); + } #endif #if DOUBLESIZE == 16 - if (b[0] == 0x9A && b[15] == 0xBD) { + if (b[0] == 0x9A && b[15] == 0xBF) { /* IEEE 754 128-bit little-endian */ printf("5\n"); exit(0); } - if (b[0] == 0x9A && b[15] == 0xCD) { + if (b[0] == 0xBF && b[15] == 0x9A) { /* IEEE 754 128-bit big-endian */ printf("6\n"); exit(0); diff --git a/Porting/Glossary b/Porting/Glossary index 1a9d770..f0970a2 100644 --- a/Porting/Glossary +++ b/Porting/Glossary @@ -2647,6 +2647,8 @@ doublekind (doublekind.U): 4 = IEEE 754 64-bit big big endian, 5 = IEEE 754 128-bit big little endian, 6 = IEEE 754 128-bit big big endian, + 7 = IEEE 754 64-bit big mixed endian le-be, + 8 = IEEE 754 64-bit big mixed endian be-le, -1 = unknown format. doublesize (doublesize.U): diff --git a/config_h.SH b/config_h.SH index 3e6e5d2..c3b5642 100755 --- a/config_h.SH +++ b/config_h.SH @@ -2712,6 +2712,8 @@ sed <<!GROK!THIS! >$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un * DOUBLE_IS_IEEE_754_64_BIT_BIG_ENDIAN * DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN * DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN + * DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_LE_BE + * DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_BE_LE * DOUBLE_IS_UNKNOWN_FORMAT */ #define DOUBLEKIND $doublekind /**/ @@ -2721,6 +2723,8 @@ sed <<!GROK!THIS! >$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un #define DOUBLE_IS_IEEE_754_64_BIT_BIG_ENDIAN 4 #define DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN 5 #define DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN 6 +#define DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_LE_BE 7 +#define DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_BE_LE 8 #define DOUBLE_IS_UNKNOWN_FORMAT -1 /* EBCDIC: diff --git a/sv.c b/sv.c index f398a93..27fc0da 100644 --- a/sv.c +++ b/sv.c @@ -10781,8 +10781,10 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen, * Also: the S_hextract() doesn't handle 32-bit or 128-bit doubles. */ #if defined(DOUBLE_LITTLE_ENDIAN) || defined(LONGDOUBLE_LITTLE_ENDIAN) # define HEXTRACT_LITTLE_ENDIAN -#else +#elif defined(DOUBLE_BIG_ENDIAN) || defined(LONGDOUBLE_BIG_ENDIAN) # define HEXTRACT_BIG_ENDIAN +#else +# define HEXTRACT_MIX_ENDIAN #endif /* S_hextract() is a helper for Perl_sv_vcatpvfn_flags, for extracting @@ -11006,11 +11008,31 @@ S_hextract(pTHX_ const NV nv, int* exponent, U8* vhex, U8* vend) for (ix = 5; ix >= 0; ix--) { HEXTRACT_BYTE(ix); } -# else +# elif defined(HEXTRACT_BIG_ENDIAN) HEXTRACT_LO_NYBBLE(1); for (ix = 2; ix < NVSIZE; ix++) { HEXTRACT_BYTE(ix); } +# else +# if DOUBLEKIND == DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_LE_BE + /* 4 5 6 7 0 1 2 3 (MSB = 7, LSB = 0, 6+7 = exponent + sign) + HEXTRACT_BYTE(2); + HEXTRACT_BYTE(1); + HEXTRACT_BYTE(7); + HEXTRACT_BYTE(6); + HEXTRACT_BYTE(5); + HEXTRACT_BYTE(4); +# elif DOUBLEKIND == DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_BE_LE + /* 3 2 1 0 7 6 5 4 (MSB = 7, LSB = 0, 0+1 = sign+exponent) */ + HEXTRACT_BYTE(4); + HEXTRACT_BYTE(5); + HEXTRACT_BYTE(6); + HEXTRACT_BYTE(7); + HEXTRACT_BYTE(0); + HEXTRACT_BYTE(1); +# else +# error "Unknown DOUBLEKIND" +# endif # endif #endif /* Croak for various reasons: if the output pointer escaped the -- Perl5 Master Repository
