Hi all,

attached is a small patch including the following fixes and improvements for 
building on big-endian platforms:
- fix newer gcc versions nagging about fishy pointer operations;
- on the PowerPC, use byte-reverse inline assembly operations - the improvement 
will be tiny, but on ageing systems, every cloc cycle counts... ;-)

BTW, IMHO the patched file Platform.h could also be used in the GarminDev 
project, as they basically serve exactly the same purpose.

Best, Albrecht.
Index: src/Platform.h
===================================================================
--- src/Platform.h	(Revision 2849)
+++ src/Platform.h	(Arbeitskopie)
@@ -32,9 +32,9 @@
 
     The `configure' script in the top-level folder tries to detect if your machine is a
     little endian (like Intel or ARM) or a big endian (like PowerPC or Sparc).  In the latter
-    case, it defines the macro WORDS_BIGENDIAN.  In an other test, it checks if your machine
+    case, it defines the macro HAVE_BIGENDIAN.  In an other test, it checks if your machine
     supports accessing unaligned memory (like Intel or PowerPC) or if such accesses would fail
-    (as an ARM or Sparc).  If unaligned accesses are supported, the macro CAN_UNALIGNED will
+    (as on ARM or Sparc).  If unaligned accesses are supported, the macro CAN_UNALIGNED will
     be defined.  Of course, the file config.h from the top-level folder has to be included.
 
     2. How to access data
@@ -92,7 +92,7 @@
 #ifndef __PLATFORM_H__
 #define __PLATFORM_H__
 
-// include platform setup (WORDS_BIGENDIAN, CAN_UNALIGNED)
+// include platform setup (HAVE_BIGENDIAN, CAN_UNALIGNED)
 #include "config.h"
 
 // need integer type definitions with fixed width
@@ -192,18 +192,30 @@ __gar_endian_int64_t(int64_t x)
 static inline float
 __gar_endian_float(float x)
 {
-    uint32_t __uv = gar_endian(uint32_t, *(uint32_t *)&x);
-    return *(float *) &__uv;
+    union {
+        uint32_t _u;
+        float _f;
+    } _v;
+    
+    _v._f = x;
+    _v._u = gar_endian(uint32_t, _v._u);
+    return _v._f;
 }
 
 
 static inline double
 __gar_endian_double(double x)
 {
-    uint64_t __uv = gar_endian(uint64_t, *(uint64_t *)&x);
-    return *(double *) &__uv;
+    union {
+        uint64_t _u;
+        double _d;
+    } _v;
+    
+    _v._d = x;
+    _v._u = gar_endian(uint64_t, _v._u);
+    return _v._d;
 }
-#endif                           // WORDS_BIGENDIAN
+#endif                           // HAVE_BIGENDIAN
 
 // --------------------------------------------------------------------------------------------
 // macros to deal with pointers or unaligned arguments
@@ -268,22 +280,45 @@ __gar_ptr_store_uint24_t(uint8_t * p, uint32_t src
 #define gar_store(t, dst, src)      gar_ptr_store(t, (uint8_t *)&(dst), src)
 
 // load from pointer - read'n'shift bytes
+// use Byte-Reverse operations for PowerPC
 static inline uint16_t
 __gar_ptr_load_uint16_t(const uint8_t *p)
 {
+#ifdef __powerpc__
+    register uint16_t temp;
+
+    asm __volatile__ ("lhbrx %0,0,%1" : "=r" (temp) : "b" (p), "m" (*p));
+    return temp;
+#else
     return (uint16_t)(p[0] | (p[1] << 8));
+#endif
 }
 
 static inline uint32_t
 __gar_ptr_load_uint24_t(const uint8_t *p)
 {
+#ifdef __powerpc__
+    register uint32_t temp;
+
+    asm __volatile__ ("lwbrx %0,0,%1"       : "=r" (temp) : "b" (p), "m" (*p));
+    asm __volatile__ ("rlwinm %0,%1,0,8,31" : "=r" (temp) : "r" (temp));
+    return temp;
+#else
     return (uint32_t)(p[0] | (p[1] << 8) | (p[2] << 16));
+#endif
 }
 
 static inline uint32_t
 __gar_ptr_load_uint32_t(const uint8_t *p)
 {
+#ifdef __powerpc__
+    register uint32_t temp;
+
+    asm __volatile__ ("lwbrx %0,0,%1" : "=r" (temp) : "b" (p), "m" (*p));
+    return temp;
+#else
     return (uint32_t)(p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24));
+#endif
 }
 
 static inline uint64_t
@@ -296,19 +331,41 @@ __gar_ptr_load_uint64_t(const uint8_t *p)
 static inline int16_t
 __gar_ptr_load_int16_t(const uint8_t *p)
 {
+#ifdef __powerpc__
+    register int16_t temp;
+
+    asm __volatile__ ("lhbrx %0,0,%1" : "=r" (temp) : "b" (p), "m" (*p));
+    return temp;
+#else
     return (int16_t)(p[0] | (p[1] << 8));
+#endif
 }
 
 static inline int32_t
 __gar_ptr_load_int24_t(const uint8_t *p)
 {
+#ifdef __powerpc__
+    register int32_t temp;
+
+    asm __volatile__ ("lwbrx %0,0,%1"       : "=r" (temp) : "b" (p), "m" (*p));
+    asm __volatile__ ("rlwinm %0,%1,0,8,31" : "=r" (temp) : "r" (temp));
+    return temp;
+#else
     return p[0] | (p[1] << 8) | (p[2] << 16);
+#endif
 }
 
 static inline int32_t
 __gar_ptr_load_int32_t(const uint8_t *p)
 {
+#ifdef __powerpc__
+    register int32_t temp;
+
+    asm __volatile__ ("lwbrx %0,0,%1" : "=r" (temp) : "b" (p), "m" (*p));
+    return temp;
+#else
     return (int32_t)(p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24));
+#endif
 }
 
 static inline int64_t
@@ -321,16 +378,26 @@ __gar_ptr_load_int64_t(const uint8_t *p)
 static inline float
 __gar_ptr_load_float(const uint8_t * p)
 {
-    uint32_t __uv = gar_ptr_load(uint32_t, p);
-    return *(float *) &__uv;
+    union {
+        uint32_t _u;
+        float _f;
+    } _v;
+
+    _v._u = gar_ptr_load(uint32_t, p);
+    return _v._f;
 }
 
 
 static inline double
-__gar_ptr_load_double(uint8_t * p)
+__gar_ptr_load_double(const uint8_t * p)
 {
-    uint64_t __uv = gar_ptr_load(uint64_t, p);
-    return *(double *) &__uv;
+    union {
+        uint64_t _u;
+        double _d;
+    } _v;
+
+    _v._u = gar_ptr_load(uint64_t, p);
+    return _v._d;
 }
 
 

Attachment: pgpCH21ipfCFv.pgp
Description: PGP signature

------------------------------------------------------------------------------
All the data continuously generated in your IT infrastructure contains a 
definitive record of customers, application performance, security 
threats, fraudulent activity and more. Splunk takes this data and makes 
sense of it. Business sense. IT sense. Common sense.. 
http://p.sf.net/sfu/splunk-d2d-c1
_______________________________________________
Qlandkartegt-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/qlandkartegt-users

Reply via email to