diff --git a/config/auto/byteorder.pm b/config/auto/byteorder.pm index 89f94d9a29..b86a91842b 100644 --- a/config/auto/byteorder.pm +++ b/config/auto/byteorder.pm @@ -23,7 +23,7 @@ use base qw(Parrot::Configure::Step); sub _init { my $self = shift; my %data; - $data{description} = q{Compute native byteorder and check bswap}; + $data{description} = q{Native byteorder and bswap}; $data{result} = q{}; return \%data; } @@ -34,10 +34,11 @@ sub runstep { my $byteorder = _probe_for_byteorder($conf); $self->_evaluate_byteorder($conf, $byteorder); - $self->_probe_byteswap($conf, "endian.h") || - $self->_probe_byteswap($conf, "sys/endian.h") || - $self->_probe_byteswap($conf, "byteswap.h") || - $self->_probe_byteswap($conf, "libkern/OSByteOrder.h"); + $self->_probe_byteswap($conf, "byteswap.h") || # GNU (esp. linux) + $self->_probe_byteswap($conf, "endian.h") || # Linux + $self->_probe_byteswap($conf, "sys/endian.h") || # Freebsd + $self->_probe_byteswap($conf, "sys/byteorder.h") || # BSWAP_32 on Solaris 10 + $self->_probe_byteswap($conf, "libkern/OSByteOrder.h"); # OSX return 1; } @@ -60,14 +61,14 @@ sub _evaluate_byteorder { byteorder => $byteorder, bigendian => 0 ); - $self->set_result('little-endian'); + $self->set_result('le'); } elsif ( $byteorder =~ /^(?:8765|4321)/ ) { $conf->data->set( byteorder => $byteorder, bigendian => 1 ); - $self->set_result('big-endian'); + $self->set_result('be'); } else { die "Unsupported byte-order [$byteorder]!"; @@ -77,24 +78,25 @@ sub _evaluate_byteorder { sub _probe_byteswap { my ($self, $conf, $include) = @_; - $conf->data->set( TEMP_include => $include ); my $i = $include; $i =~ s|/|_|g; $i =~ s|\.h$||g; $conf->cc_gen('config/auto/byteorder/bswap_c.in'); eval { $conf->cc_build("-DHAS_HEADER_".uc($i)) }; - my $ret = $@ ? 0 : eval $conf->cc_run(); + my $ret = $@ ? 0 : $conf->cc_run(); $conf->cc_clean(); - if ($ret) { + if ($ret and $ret ne '0x12345678') { my $i = $include; $i =~ s|/|_|g; $i =~ s|\.h$||g; - $conf->data->set( "i_".lc($i) ); - $self->set_result($include); + $conf->data->set( "i_".lc($i) => 'define'); + $self->set_result($self->result()." ".$i); + } + else { + $conf->data->set( "i_".lc($i) => undef) unless $ret; } - $conf->data->set( 'TEMP_include' => undef ); return $ret; } diff --git a/config/auto/byteorder/bswap_c.in b/config/auto/byteorder/bswap_c.in index 5159006cd3..02608a1fbe 100644 --- a/config/auto/byteorder/bswap_c.in +++ b/config/auto/byteorder/bswap_c.in @@ -7,8 +7,6 @@ Copyright (C) 2012, Parrot Foundation. #include #include -#include <@TEMP_include@> - #ifdef HAS_HEADER_BYTESWAP # include #else @@ -25,6 +23,7 @@ Copyright (C) 2012, Parrot Foundation. # endif # else # ifdef HAS_HEADER_LIBKERN_OSBYTEORDER +# include # if __BYTE_ORDER == __LITTLE_ENDIAN # define bswap_16(x) OSSwapHostToBigInt16(x) # define bswap_32(x) OSSwapHostToBigInt32(x) @@ -38,12 +37,6 @@ Copyright (C) 2012, Parrot Foundation. # define bswap_64(x) OSSwapBigToHostInt64(x) # endif # endif -# else -# define bswap_16(x) { unsigned char rb[4]; SWAB_4(rb,x); memcpy(x,rb,4); } -# define bswap_32(x) { unsigned char rb[8]; SWAB_8(rb,x); memcpy(x,rb,8); } -# if __WORDSIZE == 64 -# define bswap_64(x) { unsigned char rb[16]; SWAB_16(rb,x); memcpy(x,rb,16); } -# endif # endif # endif #endif @@ -51,12 +44,13 @@ Copyright (C) 2012, Parrot Foundation. int main() { - long l = 0x12345678; - bswap_16(l); - bswap_32(l); + unsigned long l = 0x12345678; + l = bswap_16((short)l); + l = bswap_32(l); #if __WORDSIZE == 64 - bswap_64(l); + l = bswap_64(l); #endif + printf("0x%lx", l); return EXIT_SUCCESS; } diff --git a/config/gen/makefiles/root.in b/config/gen/makefiles/root.in index 163202b6c6..f31289fe8f 100644 --- a/config/gen/makefiles/root.in +++ b/config/gen/makefiles/root.in @@ -1708,6 +1708,7 @@ src/packfile/output$(O) : \ src/packfile/pf_items$(O) : \ $(PARROT_H_HEADERS) \ + $(INC_DIR)/bswap.h \ src/packfile/pf_items.str \ src/packfile/pf_items.c diff --git a/include/parrot/bswap.h b/include/parrot/bswap.h index 3e43c7d107..4fb68827bf 100644 --- a/include/parrot/bswap.h +++ b/include/parrot/bswap.h @@ -6,14 +6,15 @@ */ #ifdef HAS_HEADER_BYTESWAP -# include +# include /* GNU */ #else -# ifdef HAS_HEADER_ENDIAN +# ifdef HAS_HEADER_ENDIAN /* linux */ # include -# elif defined(HAS_HEADER_SYS_ENDIAN) +# elif defined(HAS_HEADER_SYS_ENDIAN) /* FreeBSD */ # include # endif -# if defined(HAS_HEADER_ENDIAN) || defined(HAS_HEADER_SYS_ENDIAN) +# if defined(HAS_HEADER_ENDIAN) \ + || defined(HAS_HEADER_SYS_ENDIAN) # define bswap_16(x) __bswap_16(x) # define bswap_32(x) __bswap_32(x) # if __WORDSIZE == 64 @@ -21,25 +22,64 @@ # endif # else # ifdef HAS_HEADER_LIBKERN_OSBYTEORDER -# if __BYTE_ORDER == __LITTLE_ENDIAN -# define bswap_16(x) OSSwapHostToBigInt16(x) -# define bswap_32(x) OSSwapHostToBigInt32(x) +# include +# define bswap_16(x) OSSwapInt16(x) +# define bswap_32(x) OSSwapInt32(x) +# if __WORDSIZE == 64 +# define bswap_64(x) OSSwapInt64(x) +# endif +# else +# ifdef HAS_HEADER_SYS_BYTEORDER +# define bswap_16(x) BSWAP_16(x) +# define bswap_32(x) BSWAP_32(x) # if __WORDSIZE == 64 -# define bswap_64(x) OSSwapHostToBigInt64(x) +# define bswap_64(x) BSWAP_64(x) # endif # else -# define bswap_16(x) OSSwapBigToHostInt16(x) -# define bswap_32(x) OSSwapBigToHostInt32(x) -# if __WORDSIZE == 64 -# define bswap_64(x) OSSwapBigToHostInt64(x) +# ifdef __MSC_VER +# define bswap_16(x) _byteswap_ushort(x) +# define bswap_32(x) _byteswap_ulong(x) +# define bswap_64(x) _byteswap_uint64(x) +# else + /* lost */ +# define bswap_16(x) \ + ({ \ + Parrot_UInt2 __x = (x); \ + ((Parrot_UInt2)( \ + (((Parrot_UInt2)(__x) & (Parrot_UInt2)0x00ffU) << 8) | \ + (((Parrot_UInt2)(__x) & (Parrot_UInt2)0xff00U) >> 8) )); \ + }) +# define bswap_32(x) \ + ({ \ + Parrot_UInt4 __x = (x); \ + ((Parrot_UInt4)( \ + (((Parrot_UInt4)(__x) & (Parrot_UInt4)0x000000ffUL) << 24) | \ + (((Parrot_UInt4)(__x) & (Parrot_UInt4)0x0000ff00UL) << 8) | \ + (((Parrot_UInt4)(__x) & (Parrot_UInt4)0x00ff0000UL) >> 8) | \ + (((Parrot_UInt4)(__x) & (Parrot_UInt4)0xff000000UL) >> 24) )); \ + }) +# if __WORDSIZE == 64 +# define bswap_64(x) \ + ({ \ + Parrot_UInt8 __x = (x); \ + ((Parrot_UInt8)( \ + (Parrot_UInt8)(((Parrot_UInt8)(__x) & (Parrot_UInt8)0x00000000000000ffULL) << 56) | \ + (Parrot_UInt8)(((Parrot_UInt8)(__x) & (Parrot_UInt8)0x000000000000ff00ULL) << 40) | \ + (Parrot_UInt8)(((Parrot_UInt8)(__x) & (Parrot_UInt8)0x0000000000ff0000ULL) << 24) | \ + (Parrot_UInt8)(((Parrot_UInt8)(__x) & (Parrot_UInt8)0x00000000ff000000ULL) << 8) | \ + (Parrot_UInt8)(((Parrot_UInt8)(__x) & (Parrot_UInt8)0x000000ff00000000ULL) >> 8) | \ + (Parrot_UInt8)(((Parrot_UInt8)(__x) & (Parrot_UInt8)0x0000ff0000000000ULL) >> 24) | \ + (Parrot_UInt8)(((Parrot_UInt8)(__x) & (Parrot_UInt8)0x00ff000000000000ULL) >> 40) | \ + (Parrot_UInt8)(((Parrot_UInt8)(__x) & (Parrot_UInt8)0xff00000000000000ULL) >> 56) )); \ + }) +# else +# define bswap_64(x) ({ \ + unsigned char rb[16]; \ + SWAB_16(rb,(const unsigned char *)x); \ + memcpy(x,rb,16); }) +# endif # endif # endif -# else -# define bswap_16(x) { unsigned char rb[4]; SWAB_4(rb,x); memcpy(x,rb,4); } -# define bswap_32(x) { unsigned char rb[8]; SWAB_8(rb,x); memcpy(x,rb,8); } -# if __WORDSIZE == 64 -# define bswap_64(x) { unsigned char rb[16]; SWAB_16(rb,x); memcpy(x,rb,16); } -# endif # endif # endif #endif @@ -126,6 +166,26 @@ rb[30] = b[1]; \ rb[31] = b[0]; +static inline Parrot_UInt2 bswap16(Parrot_UInt2 x) +{ + return bswap_16(x); +} + +static inline Parrot_UInt4 bswap32(Parrot_UInt4 x) +{ + return bswap_32(x); +} + +static inline Parrot_UInt8 bswap64(Parrot_UInt8 x) +{ +#ifdef bswap_64 + return bswap_64(x); +#else + unsigned char rb[16]; + SWAB_16(rb,(const unsigned char *)x); + return rb; +#endif +} /* * Local variables: diff --git a/src/packfile/pf_items.c b/src/packfile/pf_items.c index cbc57832be..faaa4b51fd 100644 --- a/src/packfile/pf_items.c +++ b/src/packfile/pf_items.c @@ -32,8 +32,7 @@ for "little endian". */ #include "parrot/parrot.h" -/* FIXME: config probe (endian/byteswap/osx/manually) */ -#include +#include "parrot/bswap.h" #include "pf_items.str" /* HEADERIZER HFILE: include/parrot/packfile.h */ @@ -277,54 +276,6 @@ static opcode_t fetch_op_le_8(ARGIN(const unsigned char *b)) */ #define OFFS(pf, cursor) ((pf) ? ((const char *)(cursor) - (const char *)((pf)->src)) : 0) -#define SWAB_4(rb,b) \ - rb[0] = b[3]; \ - rb[1] = b[2]; \ - rb[2] = b[1]; \ - rb[3] = b[0] - -#define SWAB_8(rb,b) \ - rb[0] = b[7]; \ - rb[1] = b[6]; \ - rb[2] = b[5]; \ - rb[3] = b[4]; \ - rb[4] = b[3]; \ - rb[5] = b[2]; \ - rb[6] = b[1]; \ - rb[7] = b[0] - -#define SWAB_12(rb,b) \ - rb[0] = b[11]; \ - rb[1] = b[10]; \ - rb[2] = b[9]; \ - rb[3] = b[8]; \ - rb[4] = b[7]; \ - rb[5] = b[6]; \ - rb[6] = b[5]; \ - rb[7] = b[4]; \ - rb[8] = b[3]; \ - rb[9] = b[2]; \ - rb[10] = b[1]; \ - rb[11] = b[0] - -#define SWAB_16(rb,b) \ - rb[0] = b[15]; \ - rb[1] = b[14]; \ - rb[2] = b[13]; \ - rb[3] = b[12]; \ - rb[4] = b[11]; \ - rb[5] = b[10]; \ - rb[6] = b[9]; \ - rb[7] = b[8]; \ - rb[8] = b[7]; \ - rb[9] = b[6]; \ - rb[10] = b[5]; \ - rb[11] = b[4]; \ - rb[12] = b[3]; \ - rb[13] = b[2]; \ - rb[14] = b[1]; \ - rb[15] = b[0] - /* * low level FLOATVAL fetch and convert functions (see packfile.h) * @@ -1085,7 +1036,7 @@ PF_fetch_number(ARGIN_NULLOK(PackFile *pf), ARGIN(const opcode_t **stream)) if (NUMVAL_SIZE == 8 && pf->header->floattype == FLOATTYPE_10) { double d; int floatsize = pf->header->wordsize == 8 ? 16 : 12; - (pf->fetch_nv)((unsigned char *)&d, (const unsigned char *) *stream); + (pf->fetch_nv)((unsigned char *)&d, (const unsigned char *)*stream); f = d; *((const unsigned char **) (stream)) += floatsize; } @@ -1098,30 +1049,20 @@ PF_fetch_number(ARGIN_NULLOK(PackFile *pf), ARGIN(const opcode_t **stream)) /* and not already endianized in fetcher */ && NUMVAL_SIZE != floatsize ) { - const unsigned char *c = (const unsigned char *)*stream; -#if 0 - /* can swab in native wordsize? */ - if (floatsize <= INTVAL_SIZE) { - if (floatsize == 8) - bswap_64(&c); - else if (floatsize == 4) - bswap_32(&c); - else if (floatsize == 2) - bswap_16(&c); + if (floatsize == 8) { + *((const unsigned char **)stream) = bswap64((Parrot_UInt8)*stream); } - else -#endif - { - if (floatsize == 8) { - unsigned char rb[8]; - SWAB_8(rb, c); - memcpy(*stream, rb, 8); - } - else if (floatsize == 16) { - unsigned char rb[16]; - SWAB_16(rb, c); - memcpy(*stream, rb, 16); - } + else if (floatsize == 4) { + *((const unsigned char **)stream) = bswap32((Parrot_UInt4)*stream); + } + else if (floatsize == 2) { + *((const unsigned char **)stream) = bswap16((Parrot_UInt2)*stream); + } + else if (floatsize == 16) { + unsigned char rb[16]; + const unsigned char *c = (const unsigned char *) *stream; + SWAB_16(rb, c); + memcpy(*((const unsigned char **)stream), rb, 16); } } (pf->fetch_nv)((unsigned char *)&f, (const unsigned char *) *stream); @@ -1657,20 +1598,10 @@ fetch_iv_le(INTVAL w) return w; #else # if INTVAL_SIZE == 4 - return (w << 24) | ((w & 0xff00) << 8) | ((w & 0xff0000) >> 8) | (w >> 24); + return bswap32(w); # else # if INTVAL_SIZE == 8 - INTVAL r; - - r = w << 56; - r |= (w & 0xff00) << 40; - r |= (w & 0xff0000) << 24; - r |= (w & 0xff000000) << 8; - r |= (w & 0xff00000000) >> 8; - r |= (w & 0xff0000000000) >> 24; - r |= (w & 0xff000000000000) >> 40; - r |= (w & 0xff00000000000000) >> 56; - return r; + return bswap64(w); # else Parrot_x_force_error_exit(NULL, 1, "Unsupported INTVAL_SIZE=%d\n", INTVAL_SIZE); @@ -1701,19 +1632,10 @@ fetch_iv_be(INTVAL w) return w; #else # if INTVAL_SIZE == 4 - return (w << 24) | ((w & 0xff00) << 8) | ((w & 0xff0000) >> 8) | (w >> 24); + return bswap32(w); # else # if INTVAL_SIZE == 8 - INTVAL r; - r = w << 56; - r |= (w & 0xff00) << 40; - r |= (w & 0xff0000) << 24; - r |= (w & 0xff000000) << 8; - r |= (w & 0xff00000000) >> 8; - r |= (w & 0xff0000000000) >> 24; - r |= (w & 0xff000000000000) >> 40; - r |= (w & 0xff00000000000000) >> 56; - return r; + return bswap64(w); # else Parrot_x_force_error_exit(NULL, 1, "Unsupported INTVAL_SIZE=%d\n", INTVAL_SIZE); # endif @@ -1742,20 +1664,9 @@ fetch_op_be(opcode_t w) return w; #else # if OPCODE_T_SIZE == 4 - return (w << 24) | ((w & 0x0000ff00) << 8) | ((w & 0x00ff0000) >> 8) | - ((w & 0xff000000) >> 24); + return bswap32(w); # else - opcode_t r; - - r = w << 56; - r |= (w & 0xff00) << 40; - r |= (w & 0xff0000) << 24; - r |= (w & 0xff000000) << 8; - r |= (w & 0xff00000000) >> 8; - r |= (w & 0xff0000000000) >> 24; - r |= (w & 0xff000000000000) >> 40; - r |= (w & 0xff00000000000000) >> 56; - return r; + return bswap64(w); # endif #endif } @@ -1781,20 +1692,9 @@ fetch_op_le(opcode_t w) return w; #else # if OPCODE_T_SIZE == 4 - return (w << 24) | ((w & 0x0000ff00) << 8) | ((w & 0x00ff0000) >> 8) | - ((w & 0xff000000) >> 24); + return bswap32(w); # else - opcode_t r; - - r = w << 56; - r |= (w & 0xff00) << 40; - r |= (w & 0xff0000) << 24; - r |= (w & 0xff000000) << 8; - r |= (w & 0xff00000000) >> 8; - r |= (w & 0xff0000000000) >> 24; - r |= (w & 0xff000000000000) >> 40; - r |= (w & 0xff00000000000000) >> 56; - return r; + return bswap64(w); # endif #endif } @@ -1829,7 +1729,8 @@ fetch_buf_be_4(ARGOUT(unsigned char *rb), ARGIN(const unsigned char *b)) #if PARROT_BIGENDIAN memcpy(rb, b, 4); #else - SWAB_4(rb,b); + memcpy(rb, bswap16((Parrot_UInt2)*b), 4); + //SWAB_4(rb,b); #endif } @@ -1851,7 +1752,8 @@ fetch_buf_le_4(ARGOUT(unsigned char *rb), ARGIN(const unsigned char *b)) #if !PARROT_BIGENDIAN memcpy(rb, b, 4); #else - SWAB_4(rb,b); + memcpy(rb, bswap16((Parrot_UInt2)*b), 4); + //SWAB_4(rb,b); #endif } @@ -1873,7 +1775,8 @@ fetch_buf_be_8(ARGOUT(unsigned char *rb), ARGIN(const unsigned char *b)) #if PARROT_BIGENDIAN memcpy(rb, b, 8); #else - SWAB_8(rb,b); + memcpy(rb, bswap32((Parrot_UInt4)*b), 8); + //SWAB_8(rb,b); #endif } @@ -1895,7 +1798,8 @@ fetch_buf_le_8(ARGOUT(unsigned char *rb), ARGIN(const unsigned char *b)) #if !PARROT_BIGENDIAN memcpy(rb, b, 8); #else - SWAB_8(rb,b); + memcpy(rb, bswap32((Parrot_UInt4)*b), 8); + //SWAB_8(rb,b); #endif } @@ -1919,7 +1823,7 @@ fetch_buf_le_12(ARGOUT(unsigned char *rb), ARGIN(const unsigned char *b)) #else SWAB_12(rb,b); # if 0 - /* what ?? */ + /* XXX I'm sceptical */ rb[0] = b[9]; rb[1] = b[8]; rb[2] = b[11]; @@ -1976,7 +1880,8 @@ fetch_buf_le_16(ARGOUT(unsigned char *rb), ARGIN(const unsigned char *b)) #if !PARROT_BIGENDIAN memcpy(rb, b, 16); #else - SWAB_16(rb,b); + memcpy(rb, bswap64((Parrot_UInt8)*b), 16); + //SWAB_16(rb,b); #endif } @@ -1998,7 +1903,8 @@ fetch_buf_be_16(ARGOUT(unsigned char *rb), ARGIN(const unsigned char *b)) #if PARROT_BIGENDIAN memcpy(rb, b, 16); #else - SWAB_16(rb,b); + memcpy(rb, bswap64((Parrot_UInt8)*b), 16); + //SWAB_16(rb,b); #endif } @@ -2020,38 +1926,7 @@ fetch_buf_le_32(ARGOUT(unsigned char *rb), ARGIN(const unsigned char *b)) #if !PARROT_BIGENDIAN memcpy(rb, b, 32); #else - rb[0] = b[31]; - rb[1] = b[30]; - rb[2] = b[29]; - rb[3] = b[28]; - rb[4] = b[27]; - rb[5] = b[26]; - rb[6] = b[25]; - rb[7] = b[24]; - rb[8] = b[23]; - rb[9] = b[22]; - rb[10] = b[21]; - rb[11] = b[20]; - rb[12] = b[19]; - rb[13] = b[18]; - rb[14] = b[17]; - rb[15] = b[16]; - rb[16] = b[15]; - rb[17] = b[14]; - rb[18] = b[13]; - rb[19] = b[12]; - rb[20] = b[11]; - rb[21] = b[10]; - rb[22] = b[9]; - rb[23] = b[8]; - rb[24] = b[7]; - rb[25] = b[6]; - rb[26] = b[5]; - rb[27] = b[4]; - rb[28] = b[3]; - rb[29] = b[2]; - rb[30] = b[1]; - rb[31] = b[0]; + SWAB_32(rb,b); #endif } @@ -2073,38 +1948,7 @@ fetch_buf_be_32(ARGOUT(unsigned char *rb), ARGIN(const unsigned char *b)) #if PARROT_BIGENDIAN memcpy(rb, b, 32); #else - rb[0] = b[31]; - rb[1] = b[30]; - rb[2] = b[29]; - rb[3] = b[28]; - rb[4] = b[27]; - rb[5] = b[26]; - rb[6] = b[25]; - rb[7] = b[24]; - rb[8] = b[23]; - rb[9] = b[22]; - rb[10] = b[21]; - rb[11] = b[20]; - rb[12] = b[19]; - rb[13] = b[18]; - rb[14] = b[17]; - rb[15] = b[16]; - rb[16] = b[15]; - rb[17] = b[14]; - rb[18] = b[13]; - rb[19] = b[12]; - rb[20] = b[11]; - rb[21] = b[10]; - rb[22] = b[9]; - rb[23] = b[8]; - rb[24] = b[7]; - rb[25] = b[6]; - rb[26] = b[5]; - rb[27] = b[4]; - rb[28] = b[3]; - rb[29] = b[2]; - rb[30] = b[1]; - rb[31] = b[0]; + SWAB_32(rb,b); #endif }