*(uint8_t *)ptr = v;
}
-#ifdef WORDS_BIGENDIAN
+/* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the
+ kernel handles unaligned load/stores may give better results, but
+ it is a system wide setting : bad */
+#if defined(WORDS_BIGENDIAN) || defined(__arm__)
/* conservative code for little endian unaligned accesses */
static inline int lduw(void *ptr)
return u.f;
}
+static inline void stfl(void *ptr, float v)
+{
+ union {
+ float f;
+ uint32_t i;
+ } u;
+ u.f = v;
+ stl(ptr, u.i);
+}
+
+#if defined(__arm__) && !defined(WORDS_BIGENDIAN)
+
+/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */
static inline double ldfq(void *ptr)
{
union {
double d;
- uint64_t i;
+ uint32_t tab[2];
} u;
- u.i = ldq(ptr);
+ u.tab[1] = ldl(ptr);
+ u.tab[0] = ldl(ptr + 4);
return u.d;
}
-static inline void stfl(void *ptr, float v)
+static inline void stfq(void *ptr, double v)
{
union {
- float f;
- uint32_t i;
+ double d;
+ uint32_t tab[2];
} u;
- u.f = v;
- stl(ptr, u.i);
+ u.d = v;
+ stl(ptr, u.tab[1]);
+ stl(ptr + 4, u.tab[0]);
+}
+
+#else
+static inline double ldfq(void *ptr)
+{
+ union {
+ double d;
+ uint64_t i;
+ } u;
+ u.i = ldq(ptr);
+ return u.d;
}
static inline void stfq(void *ptr, double v)
u.d = v;
stq(ptr, u.i);
}
+#endif
#else
}
#endif
+#ifdef __arm__
+static inline int testandset (int *spinlock)
+{
+ register unsigned int ret;
+ __asm__ __volatile__("swp %0, %1, [%2]"
+ : "=r"(ret)
+ : "0"(1), "r"(spinlock));
+
+ return ret;
+}
+#endif
+
typedef int spinlock_t;
#define SPIN_LOCK_UNLOCKED 0
#endif
+#ifdef __arm__
+static inline void flush_icache_range(unsigned long start, unsigned long stop)
+{
+ register unsigned long _beg __asm ("a1") = start;
+ register unsigned long _end __asm ("a2") = stop;
+ register unsigned long _flg __asm ("a3") = 0;
+ __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
+}
+#endif
+
extern FILE *logfile;
extern int loglevel;
NB_OPS,
};
+#include "dyngen.h"
#include "op-i386.h"
/* operand size */