Add compile-time option -DSQLITE_MIXED_ENDIAN_64BIT_FLOAT=1 that uses
mixed-endian doubles.  This is needed on ARM7 to make database file
formats compatible with all other processors.  Tickets #2278 and #2335. (CVS 3913)

FossilOrigin-Name: 2a178d0c7950c9d403c0bc43c2043de945fb24e0
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 8721cd5..c2f841d 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.553 2007/04/26 14:42:36 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.554 2007/05/04 11:59:32 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -75,6 +75,7 @@
 # endif
 # define SQLITE_OMIT_DATETIME_FUNCS 1
 # define SQLITE_OMIT_TRACE 1
+# undef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
 #endif
 #ifndef SQLITE_BIG_DBL
 # define SQLITE_BIG_DBL (1e99)
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index b3f903c..83fe3e9 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -1768,6 +1768,32 @@
 }
 
 /*
+** If we are on an architecture with mixed-endian floating 
+*** points (ex: ARM7) then swap the lower 4 bytes with the 
+** upper 4 bytes.  Return the result.
+**
+** For most (sane) architectures, this is a no-op.
+*/
+#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
+static double floatSwap(double in){
+  union {
+    double r;
+    u32 i[2];
+  } u;
+  u32 t;
+
+  u.r = in;
+  t = u.i[0];
+  u.i[0] = u.i[1];
+  u.i[1] = t;
+  return u.r;
+}
+# define swapMixedEndianFloat(X)  X = floatSwap(X)
+#else
+# define swapMixedEndianFloat(X)
+#endif
+
+/*
 ** Write the serialized data blob for the value stored in pMem into 
 ** buf. It is assumed that the caller has allocated sufficient space.
 ** Return the number of bytes written.
@@ -1795,6 +1821,7 @@
     int i;
     if( serial_type==7 ){
       assert( sizeof(v)==sizeof(pMem->r) );
+      swapMixedEndianFloat(pMem->r);
       memcpy(&v, &pMem->r, sizeof(v));
     }else{
       v = pMem->u.i;
@@ -1879,11 +1906,15 @@
       u32 y;
 #if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT)
       /* Verify that integers and floating point values use the same
-      ** byte order.  The byte order differs on some (broken) architectures.
+      ** byte order.  Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is
+      ** defined that 64-bit floating point values really are mixed
+      ** endian.
       */
       static const u64 t1 = ((u64)0x3ff00000)<<32;
       static const double r1 = 1.0;
-      assert( sizeof(r1)==sizeof(t1) && memcmp(&r1, &t1, sizeof(r1))==0 );
+      double r2 = r1;
+      swapMixedEndianFloat(r2);
+      assert( sizeof(r2)==sizeof(t1) && memcmp(&r2, &t1, sizeof(r1))==0 );
 #endif
 
       x = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
@@ -1895,7 +1926,7 @@
       }else{
         assert( sizeof(x)==8 && sizeof(pMem->r)==8 );
         memcpy(&pMem->r, &x, sizeof(x));
-        /* pMem->r = *(double*)&x; */
+        swapMixedEndianFloat(pMem->r);
         pMem->flags = MEM_Real;
       }
       return 8;