From 18770dac2e560c88daa3ca9944917be561c3548f Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Sun, 30 Jan 2011 00:58:45 +0000 Subject: Use __builtin_constant_p() to select the best byteswapping method: constant or target optimized. Same macro can then be used for constant values and inits as well as non-constant. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29171 a1c6a512-1295-4272-9138-f99709370657 --- apps/codecs/aiff_enc.c | 13 ++-- apps/codecs/libffmpegFLAC/shndec.c | 2 +- apps/codecs/wav_enc.c | 6 +- apps/codecs/wavpack_enc.c | 6 +- firmware/export/system.h | 129 +++++++++++++++++-------------- firmware/target/arm/system-arm.h | 24 ++++-- firmware/target/coldfire/system-target.h | 8 +- firmware/target/sh/system-target.h | 8 +- 8 files changed, 110 insertions(+), 86 deletions(-) diff --git a/apps/codecs/aiff_enc.c b/apps/codecs/aiff_enc.c index cfbc95196f..2d55dff755 100644 --- a/apps/codecs/aiff_enc.c +++ b/apps/codecs/aiff_enc.c @@ -56,15 +56,15 @@ struct aiff_header aiff_header = 0, /* form_size (*) */ { 'A', 'I', 'F', 'F' }, /* aiff_id */ { 'C', 'O', 'M', 'M' }, /* comm_id */ - H_TO_BE32(18), /* comm_size */ + htobe32(18), /* comm_size */ 0, /* num_channels (*) */ 0, /* num_sample_frames (*) */ - H_TO_BE16(PCM_DEPTH_BITS), /* sample_size */ + htobe16(PCM_DEPTH_BITS), /* sample_size */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* sample_rate (*) */ { 'S', 'S', 'N', 'D' }, /* ssnd_id */ 0, /* ssnd_size (*) */ - H_TO_BE32(0), /* offset */ - H_TO_BE32(0), /* block_size */ + htobe32(0), /* offset */ + htobe32(0), /* block_size */ }; /* (*) updated when finalizing file */ @@ -96,7 +96,10 @@ STATICIRAM void uint32_h_to_ieee754_extended_be(uint8_t f[10], uint32_t l) f[1] = (uint8_t)exp; /* mantissa is value left justified with most significant non-zero bit stored in bit 63 - bits 0-63 */ - *(uint32_t *)&f[2] = htobe32(l); + f[2] = (uint8_t)(l >> 24); + f[3] = (uint8_t)(l >> 16); + f[4] = (uint8_t)(l >> 8); + f[5] = (uint8_t)(l >> 0); } /* uint32_h_to_ieee754_extended_be */ /* called version often - inline */ diff --git a/apps/codecs/libffmpegFLAC/shndec.c b/apps/codecs/libffmpegFLAC/shndec.c index 78914f6252..40e7211b87 100644 --- a/apps/codecs/libffmpegFLAC/shndec.c +++ b/apps/codecs/libffmpegFLAC/shndec.c @@ -60,7 +60,7 @@ #define get_le32(gb) bswap_32(get_bits_long(gb, 32)) /* converts fourcc string to int */ -static int ff_get_fourcc(const char *s){ +static unsigned int ff_get_fourcc(const char *s){ //assert( strlen(s)==4 ); return (s[0]) + (s[1]<<8) + (s[2]<<16) + (s[3]<<24); } diff --git a/apps/codecs/wav_enc.c b/apps/codecs/wav_enc.c index b11c3a2e99..193181d825 100644 --- a/apps/codecs/wav_enc.c +++ b/apps/codecs/wav_enc.c @@ -71,14 +71,14 @@ static const struct riff_header riff_header = /* format header */ { 'W', 'A', 'V', 'E' }, /* format */ { 'f', 'm', 't', ' ' }, /* format_id */ - H_TO_LE32(16), /* format_size */ + htole32(16), /* format_size */ /* format data */ - H_TO_LE16(1), /* audio_format */ + htole16(1), /* audio_format */ 0, /* num_channels (*) */ 0, /* sample_rate (*) */ 0, /* byte_rate (*) */ 0, /* block_align (*) */ - H_TO_LE16(PCM_DEPTH_BITS), /* bits_per_sample */ + htole16(PCM_DEPTH_BITS), /* bits_per_sample */ /* data header */ { 'd', 'a', 't', 'a' }, /* data_id */ 0 /* data_size (*) */ diff --git a/apps/codecs/wavpack_enc.c b/apps/codecs/wavpack_enc.c index 652a320546..66263cf1a1 100644 --- a/apps/codecs/wavpack_enc.c +++ b/apps/codecs/wavpack_enc.c @@ -85,14 +85,14 @@ static const struct riff_header riff_header = /* format header */ { 'W', 'A', 'V', 'E' }, /* format */ { 'f', 'm', 't', ' ' }, /* format_id */ - H_TO_LE32(16), /* format_size */ + htole32(16), /* format_size */ /* format data */ - H_TO_LE16(1), /* audio_format */ + htole16(1), /* audio_format */ 0, /* num_channels (*) */ 0, /* sample_rate (*) */ 0, /* byte_rate (*) */ 0, /* block_align (*) */ - H_TO_LE16(PCM_DEPTH_BITS), /* bits_per_sample */ + htole16(PCM_DEPTH_BITS), /* bits_per_sample */ /* data header */ { 'd', 'a', 't', 'a' }, /* data_id */ 0 /* data_size (*) */ diff --git a/firmware/export/system.h b/firmware/export/system.h index 4a5dcf0ea3..b246d154a4 100644 --- a/firmware/export/system.h +++ b/firmware/export/system.h @@ -137,61 +137,6 @@ int get_cpu_boost_counter(void); #undef htobe32 #endif -/* live endianness conversion */ -#ifdef ROCKBOX_LITTLE_ENDIAN -#define letoh16(x) (x) -#define letoh32(x) (x) -#define htole16(x) (x) -#define htole32(x) (x) -#define betoh16(x) swap16(x) -#define betoh32(x) swap32(x) -#define htobe16(x) swap16(x) -#define htobe32(x) swap32(x) -#define swap_odd_even_be32(x) (x) -#define swap_odd_even_le32(x) swap_odd_even32(x) -#else -#define letoh16(x) swap16(x) -#define letoh32(x) swap32(x) -#define htole16(x) swap16(x) -#define htole32(x) swap32(x) -#define betoh16(x) (x) -#define betoh32(x) (x) -#define htobe16(x) (x) -#define htobe32(x) (x) -#define swap_odd_even_be32(x) swap_odd_even32(x) -#define swap_odd_even_le32(x) (x) -#endif - - -/* static endianness conversion */ -#define SWAP_16(x) ((typeof(x))(unsigned short)(((unsigned short)(x) >> 8) | \ - ((unsigned short)(x) << 8))) - -#define SWAP_32(x) ((typeof(x))(unsigned long)( ((unsigned long)(x) >> 24) | \ - (((unsigned long)(x) & 0xff0000ul) >> 8) | \ - (((unsigned long)(x) & 0xff00ul) << 8) | \ - ((unsigned long)(x) << 24))) - -#ifdef ROCKBOX_LITTLE_ENDIAN -#define LE_TO_H16(x) (x) -#define LE_TO_H32(x) (x) -#define H_TO_LE16(x) (x) -#define H_TO_LE32(x) (x) -#define BE_TO_H16(x) SWAP_16(x) -#define BE_TO_H32(x) SWAP_32(x) -#define H_TO_BE16(x) SWAP_16(x) -#define H_TO_BE32(x) SWAP_32(x) -#else -#define LE_TO_H16(x) SWAP_16(x) -#define LE_TO_H32(x) SWAP_32(x) -#define H_TO_LE16(x) SWAP_16(x) -#define H_TO_LE32(x) SWAP_32(x) -#define BE_TO_H16(x) (x) -#define BE_TO_H32(x) (x) -#define H_TO_BE16(x) (x) -#define H_TO_BE32(x) (x) -#endif - /* Get the byte offset of a type's member */ #define OFFSETOF(type, membername) ((off_t)&((type *)0)->membername) @@ -237,7 +182,7 @@ enum { #endif #ifdef NEED_GENERIC_BYTESWAPS -static inline uint16_t swap16(uint16_t value) +static inline uint16_t swap16_hw(uint16_t value) /* result[15..8] = value[ 7..0]; result[ 7..0] = value[15..8]; @@ -246,7 +191,7 @@ static inline uint16_t swap16(uint16_t value) return (value >> 8) | (value << 8); } -static inline uint32_t swap32(uint32_t value) +static inline uint32_t swap32_hw(uint32_t value) /* result[31..24] = value[ 7.. 0]; result[23..16] = value[15.. 8]; @@ -254,12 +199,12 @@ static inline uint32_t swap32(uint32_t value) result[ 7.. 0] = value[31..24]; */ { - uint32_t hi = swap16(value >> 16); - uint32_t lo = swap16(value & 0xffff); + uint32_t hi = swap16_hw(value >> 16); + uint32_t lo = swap16_hw(value & 0xffff); return (lo << 16) | hi; } -static inline uint32_t swap_odd_even32(uint32_t value) +static inline uint32_t swap_odd_even32_hw(uint32_t value) { /* result[31..24],[15.. 8] = value[23..16],[ 7.. 0] @@ -269,8 +214,72 @@ static inline uint32_t swap_odd_even32(uint32_t value) return (t >> 8) | ((t ^ value) << 8); } +static inline uint32_t swaw32_hw(uint32_t value) +{ + /* + result[31..16] = value[15.. 0]; + result[15.. 0] = value[31..16]; + */ + return (value >> 16) | (value << 16); +} + #endif /* NEED_GENERIC_BYTESWAPS */ +/* static endianness conversion */ +#define SWAP16_CONST(x) \ + ((typeof(x))( ((uint16_t)(x) >> 8) | ((uint16_t)(x) << 8) )) + +#define SWAP32_CONST(x) \ + ((typeof(x))( ((uint32_t)(x) >> 24) | \ + (((uint32_t)(x) & 0xff0000) >> 8) | \ + (((uint32_t)(x) & 0xff00) << 8) | \ + ((uint32_t)(x) << 24) )) + +#define SWAP_ODD_EVEN32_CONST(x) \ + ((typeof(x))( ((uint32_t)SWAP16_CONST((uint32_t)(x) >> 16) << 16) | \ + SWAP16_CONST((uint32_t)(x))) ) + +#define SWAW32_CONST(x) \ + ((typeof(x))( ((uint32_t)(x) << 16) | ((uint32_t)(x) >> 16) )) + +/* Select best method based upon whether x is a constant expression */ +#define swap16(x) \ + ( __builtin_constant_p(x) ? SWAP16_CONST(x) : (typeof(x))swap16_hw(x) ) + +#define swap32(x) \ + ( __builtin_constant_p(x) ? SWAP32_CONST(x) : (typeof(x))swap32_hw(x) ) + +#define swap_odd_even32(x) \ + ( __builtin_constant_p(x) ? SWAP_ODD_EVEN32_CONST(x) : (typeof(x))swap_odd_even32_hw(x) ) + +#define swaw32(x) \ + ( __builtin_constant_p(x) ? SWAW32_CONST(x) : (typeof(x))swaw32_hw(x) ) + + +#ifdef ROCKBOX_LITTLE_ENDIAN +#define letoh16(x) (x) +#define letoh32(x) (x) +#define htole16(x) (x) +#define htole32(x) (x) +#define betoh16(x) swap16(x) +#define betoh32(x) swap32(x) +#define htobe16(x) swap16(x) +#define htobe32(x) swap32(x) +#define swap_odd_even_be32(x) (x) +#define swap_odd_even_le32(x) swap_odd_even32(x) +#else +#define letoh16(x) swap16(x) +#define letoh32(x) swap32(x) +#define htole16(x) swap16(x) +#define htole32(x) swap32(x) +#define betoh16(x) (x) +#define betoh32(x) (x) +#define htobe16(x) (x) +#define htobe32(x) (x) +#define swap_odd_even_be32(x) swap_odd_even32(x) +#define swap_odd_even_le32(x) (x) +#endif + #ifndef BIT_N #define BIT_N(n) (1U << (n)) #endif diff --git a/firmware/target/arm/system-arm.h b/firmware/target/arm/system-arm.h index 0608f50a02..e77b786866 100644 --- a/firmware/target/arm/system-arm.h +++ b/firmware/target/arm/system-arm.h @@ -90,7 +90,7 @@ static inline void restore_interrupt(int cpsr) /* ARM_ARCH version section for architecture*/ #if ARM_ARCH >= 6 -static inline uint16_t swap16(uint16_t value) +static inline uint16_t swap16_hw(uint16_t value) /* result[15..8] = value[ 7..0]; result[ 7..0] = value[15..8]; @@ -102,7 +102,7 @@ static inline uint16_t swap16(uint16_t value) return retval; } -static inline uint32_t swap32(uint32_t value) +static inline uint32_t swap32_hw(uint32_t value) /* result[31..24] = value[ 7.. 0]; result[23..16] = value[15.. 8]; @@ -116,7 +116,7 @@ static inline uint32_t swap32(uint32_t value) return retval; } -static inline uint32_t swap_odd_even32(uint32_t value) +static inline uint32_t swap_odd_even32_hw(uint32_t value) { /* result[31..24],[15.. 8] = value[23..16],[ 7.. 0] @@ -190,7 +190,7 @@ static inline int disable_interrupt_save(int mask) #else /* ARM_ARCH < 6 */ -static inline uint16_t swap16(uint16_t value) +static inline uint16_t swap16_hw(uint16_t value) /* result[15..8] = value[ 7..0]; result[ 7..0] = value[15..8]; @@ -199,7 +199,7 @@ static inline uint16_t swap16(uint16_t value) return (value >> 8) | (value << 8); } -static inline uint32_t swap32(uint32_t value) +static inline uint32_t swap32_hw(uint32_t value) /* result[31..24] = value[ 7.. 0]; result[23..16] = value[15.. 8]; @@ -218,7 +218,7 @@ static inline uint32_t swap32(uint32_t value) return value; } -static inline uint32_t swap_odd_even32(uint32_t value) +static inline uint32_t swap_odd_even32_hw(uint32_t value) { /* result[31..24],[15.. 8] = value[23..16],[ 7.. 0] @@ -272,4 +272,16 @@ static inline int disable_interrupt_save(int mask) #endif /* ARM_ARCH */ +static inline uint32_t swaw32_hw(uint32_t value) +{ + /* + result[31..16] = value[15.. 0]; + result[15.. 0] = value[31..16]; + */ + uint32_t retval; + asm volatile ("mov %0, %1, ror #16" : + "=r"(retval) : "r"(value)); + return retval; +} + #endif /* SYSTEM_ARM_H */ diff --git a/firmware/target/coldfire/system-target.h b/firmware/target/coldfire/system-target.h index 2de8fd06c2..d1a2a1f115 100644 --- a/firmware/target/coldfire/system-target.h +++ b/firmware/target/coldfire/system-target.h @@ -132,7 +132,7 @@ static inline void restore_irq(int oldlevel) asm volatile ("move.w %0, %%sr" : : "d"(oldlevel)); } -static inline uint16_t swap16(uint16_t value) +static inline uint16_t swap16_hw(uint16_t value) /* result[15..8] = value[ 7..0]; result[ 7..0] = value[15..8]; @@ -141,7 +141,7 @@ static inline uint16_t swap16(uint16_t value) return (value >> 8) | (value << 8); } -static inline uint32_t SWAW32(uint32_t value) +static inline uint32_t swaw32_hw(uint32_t value) /* result[31..16] = value[15.. 0]; result[15.. 0] = value[31..16]; @@ -151,7 +151,7 @@ static inline uint32_t SWAW32(uint32_t value) return value; } -static inline uint32_t swap32(uint32_t value) +static inline uint32_t swap32_hw(uint32_t value) /* result[31..24] = value[ 7.. 0]; result[23..16] = value[15.. 8]; @@ -174,7 +174,7 @@ static inline uint32_t swap32(uint32_t value) return value; } -static inline uint32_t swap_odd_even32(uint32_t value) +static inline uint32_t swap_odd_even32_hw(uint32_t value) { /* result[31..24],[15.. 8] = value[23..16],[ 7.. 0] diff --git a/firmware/target/sh/system-target.h b/firmware/target/sh/system-target.h index a84ce07af9..1693a132a6 100644 --- a/firmware/target/sh/system-target.h +++ b/firmware/target/sh/system-target.h @@ -77,7 +77,7 @@ static inline void enable_irq(void) #define restore_irq(i) \ ((void)set_irq_level(i)) -static inline uint16_t swap16(uint16_t value) +static inline uint16_t swap16_hw(uint16_t value) /* result[15..8] = value[ 7..0]; result[ 7..0] = value[15..8]; @@ -88,7 +88,7 @@ static inline uint16_t swap16(uint16_t value) return result; } -static inline uint32_t SWAW32(uint32_t value) +static inline uint32_t swaw32_hw(uint32_t value) /* result[31..16] = value[15.. 0]; result[15.. 0] = value[31..16]; @@ -99,7 +99,7 @@ static inline uint32_t SWAW32(uint32_t value) return result; } -static inline uint32_t swap32(uint32_t value) +static inline uint32_t swap32_hw(uint32_t value) /* result[31..24] = value[ 7.. 0]; result[23..16] = value[15.. 8]; @@ -113,7 +113,7 @@ static inline uint32_t swap32(uint32_t value) return value; } -static inline uint32_t swap_odd_even32(uint32_t value) +static inline uint32_t swap_odd_even32_hw(uint32_t value) { /* result[31..24],[15.. 8] = value[23..16],[ 7.. 0] -- cgit v1.2.3