Skip to content

Commit

Permalink
Fix and improve bswap.h
Browse files Browse the repository at this point in the history
Add missing libkern/OSByteOrder.h
Abstract macros into static inline functions
Use fast replacement macros
Use bswap in pf_items.c
  • Loading branch information
Reini Urban committed Sep 9, 2012
1 parent f26b383 commit 775883a
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 237 deletions.
28 changes: 15 additions & 13 deletions config/auto/byteorder.pm
Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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]!";
Expand All @@ -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;
}

Expand Down
18 changes: 6 additions & 12 deletions config/auto/byteorder/bswap_c.in
Expand Up @@ -7,8 +7,6 @@ Copyright (C) 2012, Parrot Foundation.
#include <stdio.h>
#include <stdint.h>

#include <@TEMP_include@>

#ifdef HAS_HEADER_BYTESWAP
# include <byteswap.h>
#else
Expand All @@ -25,6 +23,7 @@ Copyright (C) 2012, Parrot Foundation.
# endif
# else
# ifdef HAS_HEADER_LIBKERN_OSBYTEORDER
# include <libkern/OSXByteOrder.h>
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define bswap_16(x) OSSwapHostToBigInt16(x)
# define bswap_32(x) OSSwapHostToBigInt32(x)
Expand All @@ -38,25 +37,20 @@ 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

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;
}

Expand Down
1 change: 1 addition & 0 deletions config/gen/makefiles/root.in
Expand Up @@ -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

Expand Down
96 changes: 78 additions & 18 deletions include/parrot/bswap.h
Expand Up @@ -6,40 +6,80 @@
*/

#ifdef HAS_HEADER_BYTESWAP
# include <byteswap.h>
# include <byteswap.h> /* GNU */
#else
# ifdef HAS_HEADER_ENDIAN
# ifdef HAS_HEADER_ENDIAN /* linux */
# include <endian.h>
# elif defined(HAS_HEADER_SYS_ENDIAN)
# elif defined(HAS_HEADER_SYS_ENDIAN) /* FreeBSD */
# include <sys/endian.h>
# 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
# define bswap_64(x) __bswap_64(x)
# 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 <libkern/OSByteOrder.h>
# 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
Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit 775883a

Please sign in to comment.