move unaligned memory access functions to bswap.h
This is just code movement, and moving the fpu/ include path from target-dependent to target-independent Make variables. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
789ec7ce20
commit
cbbab9226d
@ -9,7 +9,7 @@ include $(SRC_PATH)/rules.mak
|
|||||||
|
|
||||||
$(call set-vpath, $(SRC_PATH):$(SRC_PATH)/hw)
|
$(call set-vpath, $(SRC_PATH):$(SRC_PATH)/hw)
|
||||||
|
|
||||||
QEMU_CFLAGS+=-I.. -I$(SRC_PATH)/fpu
|
QEMU_CFLAGS+=-I..
|
||||||
|
|
||||||
include $(SRC_PATH)/Makefile.objs
|
include $(SRC_PATH)/Makefile.objs
|
||||||
|
|
||||||
|
474
bswap.h
474
bswap.h
@ -11,6 +11,8 @@
|
|||||||
#include <machine/bswap.h>
|
#include <machine/bswap.h>
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#include "softfloat.h"
|
||||||
|
|
||||||
#ifdef CONFIG_BYTESWAP_H
|
#ifdef CONFIG_BYTESWAP_H
|
||||||
#include <byteswap.h>
|
#include <byteswap.h>
|
||||||
#else
|
#else
|
||||||
@ -237,4 +239,476 @@ static inline uint32_t qemu_bswap_len(uint32_t value, int len)
|
|||||||
return bswap32(value) >> (32 - 8 * len);
|
return bswap32(value) >> (32 - 8 * len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
float32 f;
|
||||||
|
uint32_t l;
|
||||||
|
} CPU_FloatU;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
float64 d;
|
||||||
|
#if defined(HOST_WORDS_BIGENDIAN)
|
||||||
|
struct {
|
||||||
|
uint32_t upper;
|
||||||
|
uint32_t lower;
|
||||||
|
} l;
|
||||||
|
#else
|
||||||
|
struct {
|
||||||
|
uint32_t lower;
|
||||||
|
uint32_t upper;
|
||||||
|
} l;
|
||||||
|
#endif
|
||||||
|
uint64_t ll;
|
||||||
|
} CPU_DoubleU;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
floatx80 d;
|
||||||
|
struct {
|
||||||
|
uint64_t lower;
|
||||||
|
uint16_t upper;
|
||||||
|
} l;
|
||||||
|
} CPU_LDoubleU;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
float128 q;
|
||||||
|
#if defined(HOST_WORDS_BIGENDIAN)
|
||||||
|
struct {
|
||||||
|
uint32_t upmost;
|
||||||
|
uint32_t upper;
|
||||||
|
uint32_t lower;
|
||||||
|
uint32_t lowest;
|
||||||
|
} l;
|
||||||
|
struct {
|
||||||
|
uint64_t upper;
|
||||||
|
uint64_t lower;
|
||||||
|
} ll;
|
||||||
|
#else
|
||||||
|
struct {
|
||||||
|
uint32_t lowest;
|
||||||
|
uint32_t lower;
|
||||||
|
uint32_t upper;
|
||||||
|
uint32_t upmost;
|
||||||
|
} l;
|
||||||
|
struct {
|
||||||
|
uint64_t lower;
|
||||||
|
uint64_t upper;
|
||||||
|
} ll;
|
||||||
|
#endif
|
||||||
|
} CPU_QuadU;
|
||||||
|
|
||||||
|
/* unaligned/endian-independent pointer access */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the generic syntax is:
|
||||||
|
*
|
||||||
|
* load: ld{type}{sign}{size}{endian}_p(ptr)
|
||||||
|
*
|
||||||
|
* store: st{type}{size}{endian}_p(ptr, val)
|
||||||
|
*
|
||||||
|
* Note there are small differences with the softmmu access API!
|
||||||
|
*
|
||||||
|
* type is:
|
||||||
|
* (empty): integer access
|
||||||
|
* f : float access
|
||||||
|
*
|
||||||
|
* sign is:
|
||||||
|
* (empty): for floats or 32 bit size
|
||||||
|
* u : unsigned
|
||||||
|
* s : signed
|
||||||
|
*
|
||||||
|
* size is:
|
||||||
|
* b: 8 bits
|
||||||
|
* w: 16 bits
|
||||||
|
* l: 32 bits
|
||||||
|
* q: 64 bits
|
||||||
|
*
|
||||||
|
* endian is:
|
||||||
|
* (empty): 8 bit access
|
||||||
|
* be : big endian
|
||||||
|
* le : little endian
|
||||||
|
*/
|
||||||
|
static inline int ldub_p(const void *ptr)
|
||||||
|
{
|
||||||
|
return *(uint8_t *)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int ldsb_p(const void *ptr)
|
||||||
|
{
|
||||||
|
return *(int8_t *)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stb_p(void *ptr, int v)
|
||||||
|
{
|
||||||
|
*(uint8_t *)ptr = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
|
||||||
|
|
||||||
|
/* conservative code for little endian unaligned accesses */
|
||||||
|
static inline int lduw_le_p(const void *ptr)
|
||||||
|
{
|
||||||
|
#ifdef _ARCH_PPC
|
||||||
|
int val;
|
||||||
|
__asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
|
||||||
|
return val;
|
||||||
|
#else
|
||||||
|
const uint8_t *p = ptr;
|
||||||
|
return p[0] | (p[1] << 8);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int ldsw_le_p(const void *ptr)
|
||||||
|
{
|
||||||
|
#ifdef _ARCH_PPC
|
||||||
|
int val;
|
||||||
|
__asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
|
||||||
|
return (int16_t)val;
|
||||||
|
#else
|
||||||
|
const uint8_t *p = ptr;
|
||||||
|
return (int16_t)(p[0] | (p[1] << 8));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int ldl_le_p(const void *ptr)
|
||||||
|
{
|
||||||
|
#ifdef _ARCH_PPC
|
||||||
|
int val;
|
||||||
|
__asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr));
|
||||||
|
return val;
|
||||||
|
#else
|
||||||
|
const uint8_t *p = ptr;
|
||||||
|
return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t ldq_le_p(const void *ptr)
|
||||||
|
{
|
||||||
|
const uint8_t *p = ptr;
|
||||||
|
uint32_t v1, v2;
|
||||||
|
v1 = ldl_le_p(p);
|
||||||
|
v2 = ldl_le_p(p + 4);
|
||||||
|
return v1 | ((uint64_t)v2 << 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stw_le_p(void *ptr, int v)
|
||||||
|
{
|
||||||
|
#ifdef _ARCH_PPC
|
||||||
|
__asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr));
|
||||||
|
#else
|
||||||
|
uint8_t *p = ptr;
|
||||||
|
p[0] = v;
|
||||||
|
p[1] = v >> 8;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stl_le_p(void *ptr, int v)
|
||||||
|
{
|
||||||
|
#ifdef _ARCH_PPC
|
||||||
|
__asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr));
|
||||||
|
#else
|
||||||
|
uint8_t *p = ptr;
|
||||||
|
p[0] = v;
|
||||||
|
p[1] = v >> 8;
|
||||||
|
p[2] = v >> 16;
|
||||||
|
p[3] = v >> 24;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stq_le_p(void *ptr, uint64_t v)
|
||||||
|
{
|
||||||
|
uint8_t *p = ptr;
|
||||||
|
stl_le_p(p, (uint32_t)v);
|
||||||
|
stl_le_p(p + 4, v >> 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* float access */
|
||||||
|
|
||||||
|
static inline float32 ldfl_le_p(const void *ptr)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
float32 f;
|
||||||
|
uint32_t i;
|
||||||
|
} u;
|
||||||
|
u.i = ldl_le_p(ptr);
|
||||||
|
return u.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stfl_le_p(void *ptr, float32 v)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
float32 f;
|
||||||
|
uint32_t i;
|
||||||
|
} u;
|
||||||
|
u.f = v;
|
||||||
|
stl_le_p(ptr, u.i);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline float64 ldfq_le_p(const void *ptr)
|
||||||
|
{
|
||||||
|
CPU_DoubleU u;
|
||||||
|
u.l.lower = ldl_le_p(ptr);
|
||||||
|
u.l.upper = ldl_le_p(ptr + 4);
|
||||||
|
return u.d;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stfq_le_p(void *ptr, float64 v)
|
||||||
|
{
|
||||||
|
CPU_DoubleU u;
|
||||||
|
u.d = v;
|
||||||
|
stl_le_p(ptr, u.l.lower);
|
||||||
|
stl_le_p(ptr + 4, u.l.upper);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static inline int lduw_le_p(const void *ptr)
|
||||||
|
{
|
||||||
|
return *(uint16_t *)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int ldsw_le_p(const void *ptr)
|
||||||
|
{
|
||||||
|
return *(int16_t *)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int ldl_le_p(const void *ptr)
|
||||||
|
{
|
||||||
|
return *(uint32_t *)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t ldq_le_p(const void *ptr)
|
||||||
|
{
|
||||||
|
return *(uint64_t *)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stw_le_p(void *ptr, int v)
|
||||||
|
{
|
||||||
|
*(uint16_t *)ptr = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stl_le_p(void *ptr, int v)
|
||||||
|
{
|
||||||
|
*(uint32_t *)ptr = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stq_le_p(void *ptr, uint64_t v)
|
||||||
|
{
|
||||||
|
*(uint64_t *)ptr = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* float access */
|
||||||
|
|
||||||
|
static inline float32 ldfl_le_p(const void *ptr)
|
||||||
|
{
|
||||||
|
return *(float32 *)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline float64 ldfq_le_p(const void *ptr)
|
||||||
|
{
|
||||||
|
return *(float64 *)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stfl_le_p(void *ptr, float32 v)
|
||||||
|
{
|
||||||
|
*(float32 *)ptr = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stfq_le_p(void *ptr, float64 v)
|
||||||
|
{
|
||||||
|
*(float64 *)ptr = v;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
|
||||||
|
|
||||||
|
static inline int lduw_be_p(const void *ptr)
|
||||||
|
{
|
||||||
|
#if defined(__i386__)
|
||||||
|
int val;
|
||||||
|
asm volatile ("movzwl %1, %0\n"
|
||||||
|
"xchgb %b0, %h0\n"
|
||||||
|
: "=q" (val)
|
||||||
|
: "m" (*(uint16_t *)ptr));
|
||||||
|
return val;
|
||||||
|
#else
|
||||||
|
const uint8_t *b = ptr;
|
||||||
|
return ((b[0] << 8) | b[1]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int ldsw_be_p(const void *ptr)
|
||||||
|
{
|
||||||
|
#if defined(__i386__)
|
||||||
|
int val;
|
||||||
|
asm volatile ("movzwl %1, %0\n"
|
||||||
|
"xchgb %b0, %h0\n"
|
||||||
|
: "=q" (val)
|
||||||
|
: "m" (*(uint16_t *)ptr));
|
||||||
|
return (int16_t)val;
|
||||||
|
#else
|
||||||
|
const uint8_t *b = ptr;
|
||||||
|
return (int16_t)((b[0] << 8) | b[1]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int ldl_be_p(const void *ptr)
|
||||||
|
{
|
||||||
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
|
int val;
|
||||||
|
asm volatile ("movl %1, %0\n"
|
||||||
|
"bswap %0\n"
|
||||||
|
: "=r" (val)
|
||||||
|
: "m" (*(uint32_t *)ptr));
|
||||||
|
return val;
|
||||||
|
#else
|
||||||
|
const uint8_t *b = ptr;
|
||||||
|
return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t ldq_be_p(const void *ptr)
|
||||||
|
{
|
||||||
|
uint32_t a,b;
|
||||||
|
a = ldl_be_p(ptr);
|
||||||
|
b = ldl_be_p((uint8_t *)ptr + 4);
|
||||||
|
return (((uint64_t)a<<32)|b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stw_be_p(void *ptr, int v)
|
||||||
|
{
|
||||||
|
#if defined(__i386__)
|
||||||
|
asm volatile ("xchgb %b0, %h0\n"
|
||||||
|
"movw %w0, %1\n"
|
||||||
|
: "=q" (v)
|
||||||
|
: "m" (*(uint16_t *)ptr), "0" (v));
|
||||||
|
#else
|
||||||
|
uint8_t *d = (uint8_t *) ptr;
|
||||||
|
d[0] = v >> 8;
|
||||||
|
d[1] = v;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stl_be_p(void *ptr, int v)
|
||||||
|
{
|
||||||
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
|
asm volatile ("bswap %0\n"
|
||||||
|
"movl %0, %1\n"
|
||||||
|
: "=r" (v)
|
||||||
|
: "m" (*(uint32_t *)ptr), "0" (v));
|
||||||
|
#else
|
||||||
|
uint8_t *d = (uint8_t *) ptr;
|
||||||
|
d[0] = v >> 24;
|
||||||
|
d[1] = v >> 16;
|
||||||
|
d[2] = v >> 8;
|
||||||
|
d[3] = v;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stq_be_p(void *ptr, uint64_t v)
|
||||||
|
{
|
||||||
|
stl_be_p(ptr, v >> 32);
|
||||||
|
stl_be_p((uint8_t *)ptr + 4, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* float access */
|
||||||
|
|
||||||
|
static inline float32 ldfl_be_p(const void *ptr)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
float32 f;
|
||||||
|
uint32_t i;
|
||||||
|
} u;
|
||||||
|
u.i = ldl_be_p(ptr);
|
||||||
|
return u.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stfl_be_p(void *ptr, float32 v)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
float32 f;
|
||||||
|
uint32_t i;
|
||||||
|
} u;
|
||||||
|
u.f = v;
|
||||||
|
stl_be_p(ptr, u.i);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline float64 ldfq_be_p(const void *ptr)
|
||||||
|
{
|
||||||
|
CPU_DoubleU u;
|
||||||
|
u.l.upper = ldl_be_p(ptr);
|
||||||
|
u.l.lower = ldl_be_p((uint8_t *)ptr + 4);
|
||||||
|
return u.d;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stfq_be_p(void *ptr, float64 v)
|
||||||
|
{
|
||||||
|
CPU_DoubleU u;
|
||||||
|
u.d = v;
|
||||||
|
stl_be_p(ptr, u.l.upper);
|
||||||
|
stl_be_p((uint8_t *)ptr + 4, u.l.lower);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static inline int lduw_be_p(const void *ptr)
|
||||||
|
{
|
||||||
|
return *(uint16_t *)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int ldsw_be_p(const void *ptr)
|
||||||
|
{
|
||||||
|
return *(int16_t *)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int ldl_be_p(const void *ptr)
|
||||||
|
{
|
||||||
|
return *(uint32_t *)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t ldq_be_p(const void *ptr)
|
||||||
|
{
|
||||||
|
return *(uint64_t *)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stw_be_p(void *ptr, int v)
|
||||||
|
{
|
||||||
|
*(uint16_t *)ptr = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stl_be_p(void *ptr, int v)
|
||||||
|
{
|
||||||
|
*(uint32_t *)ptr = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stq_be_p(void *ptr, uint64_t v)
|
||||||
|
{
|
||||||
|
*(uint64_t *)ptr = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* float access */
|
||||||
|
|
||||||
|
static inline float32 ldfl_be_p(const void *ptr)
|
||||||
|
{
|
||||||
|
return *(float32 *)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline float64 ldfq_be_p(const void *ptr)
|
||||||
|
{
|
||||||
|
return *(float64 *)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stfl_be_p(void *ptr, float32 v)
|
||||||
|
{
|
||||||
|
*(float32 *)ptr = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void stfq_be_p(void *ptr, float64 v)
|
||||||
|
{
|
||||||
|
*(float64 *)ptr = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* BSWAP_H */
|
#endif /* BSWAP_H */
|
||||||
|
3
configure
vendored
3
configure
vendored
@ -233,7 +233,7 @@ QEMU_CFLAGS="-Wall -Wundef -Wwrite-strings -Wmissing-prototypes $QEMU_CFLAGS"
|
|||||||
QEMU_CFLAGS="-Wstrict-prototypes -Wredundant-decls $QEMU_CFLAGS"
|
QEMU_CFLAGS="-Wstrict-prototypes -Wredundant-decls $QEMU_CFLAGS"
|
||||||
QEMU_CFLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE $QEMU_CFLAGS"
|
QEMU_CFLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE $QEMU_CFLAGS"
|
||||||
QEMU_CFLAGS="-D_FORTIFY_SOURCE=2 $QEMU_CFLAGS"
|
QEMU_CFLAGS="-D_FORTIFY_SOURCE=2 $QEMU_CFLAGS"
|
||||||
QEMU_INCLUDES="-I. -I\$(SRC_PATH)"
|
QEMU_INCLUDES="-I. -I\$(SRC_PATH) -I\$(SRC_PATH)/fpu"
|
||||||
LDFLAGS="-g $LDFLAGS"
|
LDFLAGS="-g $LDFLAGS"
|
||||||
|
|
||||||
# make source path absolute
|
# make source path absolute
|
||||||
@ -3374,7 +3374,6 @@ else
|
|||||||
includes="-I\$(SRC_PATH)/tcg/\$(ARCH) $includes"
|
includes="-I\$(SRC_PATH)/tcg/\$(ARCH) $includes"
|
||||||
fi
|
fi
|
||||||
includes="-I\$(SRC_PATH)/tcg $includes"
|
includes="-I\$(SRC_PATH)/tcg $includes"
|
||||||
includes="-I\$(SRC_PATH)/fpu $includes"
|
|
||||||
|
|
||||||
if test "$target_user_only" = "yes" ; then
|
if test "$target_user_only" = "yes" ; then
|
||||||
libdis_config_mak=libdis-user/config.mak
|
libdis_config_mak=libdis-user/config.mak
|
||||||
|
446
cpu-all.h
446
cpu-all.h
@ -35,8 +35,6 @@
|
|||||||
* TARGET_WORDS_BIGENDIAN : same for target cpu
|
* TARGET_WORDS_BIGENDIAN : same for target cpu
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "softfloat.h"
|
|
||||||
|
|
||||||
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
|
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
|
||||||
#define BSWAP_NEEDED
|
#define BSWAP_NEEDED
|
||||||
#endif
|
#endif
|
||||||
@ -114,64 +112,6 @@ static inline void tswap64s(uint64_t *s)
|
|||||||
#define bswaptls(s) bswap64s(s)
|
#define bswaptls(s) bswap64s(s)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef union {
|
|
||||||
float32 f;
|
|
||||||
uint32_t l;
|
|
||||||
} CPU_FloatU;
|
|
||||||
|
|
||||||
/* NOTE: arm FPA is horrible as double 32 bit words are stored in big
|
|
||||||
endian ! */
|
|
||||||
typedef union {
|
|
||||||
float64 d;
|
|
||||||
#if defined(HOST_WORDS_BIGENDIAN)
|
|
||||||
struct {
|
|
||||||
uint32_t upper;
|
|
||||||
uint32_t lower;
|
|
||||||
} l;
|
|
||||||
#else
|
|
||||||
struct {
|
|
||||||
uint32_t lower;
|
|
||||||
uint32_t upper;
|
|
||||||
} l;
|
|
||||||
#endif
|
|
||||||
uint64_t ll;
|
|
||||||
} CPU_DoubleU;
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
floatx80 d;
|
|
||||||
struct {
|
|
||||||
uint64_t lower;
|
|
||||||
uint16_t upper;
|
|
||||||
} l;
|
|
||||||
} CPU_LDoubleU;
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
float128 q;
|
|
||||||
#if defined(HOST_WORDS_BIGENDIAN)
|
|
||||||
struct {
|
|
||||||
uint32_t upmost;
|
|
||||||
uint32_t upper;
|
|
||||||
uint32_t lower;
|
|
||||||
uint32_t lowest;
|
|
||||||
} l;
|
|
||||||
struct {
|
|
||||||
uint64_t upper;
|
|
||||||
uint64_t lower;
|
|
||||||
} ll;
|
|
||||||
#else
|
|
||||||
struct {
|
|
||||||
uint32_t lowest;
|
|
||||||
uint32_t lower;
|
|
||||||
uint32_t upper;
|
|
||||||
uint32_t upmost;
|
|
||||||
} l;
|
|
||||||
struct {
|
|
||||||
uint64_t lower;
|
|
||||||
uint64_t upper;
|
|
||||||
} ll;
|
|
||||||
#endif
|
|
||||||
} CPU_QuadU;
|
|
||||||
|
|
||||||
/* CPU memory access without any memory or io remapping */
|
/* CPU memory access without any memory or io remapping */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -207,392 +147,8 @@ typedef union {
|
|||||||
* user : user mode access using soft MMU
|
* user : user mode access using soft MMU
|
||||||
* kernel : kernel mode access using soft MMU
|
* kernel : kernel mode access using soft MMU
|
||||||
*/
|
*/
|
||||||
static inline int ldub_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return *(uint8_t *)ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int ldsb_p(const void *ptr)
|
/* target-endianness CPU memory access functions */
|
||||||
{
|
|
||||||
return *(int8_t *)ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stb_p(void *ptr, int v)
|
|
||||||
{
|
|
||||||
*(uint8_t *)ptr = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
|
|
||||||
|
|
||||||
/* conservative code for little endian unaligned accesses */
|
|
||||||
static inline int lduw_le_p(const void *ptr)
|
|
||||||
{
|
|
||||||
#ifdef _ARCH_PPC
|
|
||||||
int val;
|
|
||||||
__asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
|
|
||||||
return val;
|
|
||||||
#else
|
|
||||||
const uint8_t *p = ptr;
|
|
||||||
return p[0] | (p[1] << 8);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int ldsw_le_p(const void *ptr)
|
|
||||||
{
|
|
||||||
#ifdef _ARCH_PPC
|
|
||||||
int val;
|
|
||||||
__asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
|
|
||||||
return (int16_t)val;
|
|
||||||
#else
|
|
||||||
const uint8_t *p = ptr;
|
|
||||||
return (int16_t)(p[0] | (p[1] << 8));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int ldl_le_p(const void *ptr)
|
|
||||||
{
|
|
||||||
#ifdef _ARCH_PPC
|
|
||||||
int val;
|
|
||||||
__asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr));
|
|
||||||
return val;
|
|
||||||
#else
|
|
||||||
const uint8_t *p = ptr;
|
|
||||||
return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t ldq_le_p(const void *ptr)
|
|
||||||
{
|
|
||||||
const uint8_t *p = ptr;
|
|
||||||
uint32_t v1, v2;
|
|
||||||
v1 = ldl_le_p(p);
|
|
||||||
v2 = ldl_le_p(p + 4);
|
|
||||||
return v1 | ((uint64_t)v2 << 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stw_le_p(void *ptr, int v)
|
|
||||||
{
|
|
||||||
#ifdef _ARCH_PPC
|
|
||||||
__asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr));
|
|
||||||
#else
|
|
||||||
uint8_t *p = ptr;
|
|
||||||
p[0] = v;
|
|
||||||
p[1] = v >> 8;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stl_le_p(void *ptr, int v)
|
|
||||||
{
|
|
||||||
#ifdef _ARCH_PPC
|
|
||||||
__asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr));
|
|
||||||
#else
|
|
||||||
uint8_t *p = ptr;
|
|
||||||
p[0] = v;
|
|
||||||
p[1] = v >> 8;
|
|
||||||
p[2] = v >> 16;
|
|
||||||
p[3] = v >> 24;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stq_le_p(void *ptr, uint64_t v)
|
|
||||||
{
|
|
||||||
uint8_t *p = ptr;
|
|
||||||
stl_le_p(p, (uint32_t)v);
|
|
||||||
stl_le_p(p + 4, v >> 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* float access */
|
|
||||||
|
|
||||||
static inline float32 ldfl_le_p(const void *ptr)
|
|
||||||
{
|
|
||||||
union {
|
|
||||||
float32 f;
|
|
||||||
uint32_t i;
|
|
||||||
} u;
|
|
||||||
u.i = ldl_le_p(ptr);
|
|
||||||
return u.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stfl_le_p(void *ptr, float32 v)
|
|
||||||
{
|
|
||||||
union {
|
|
||||||
float32 f;
|
|
||||||
uint32_t i;
|
|
||||||
} u;
|
|
||||||
u.f = v;
|
|
||||||
stl_le_p(ptr, u.i);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline float64 ldfq_le_p(const void *ptr)
|
|
||||||
{
|
|
||||||
CPU_DoubleU u;
|
|
||||||
u.l.lower = ldl_le_p(ptr);
|
|
||||||
u.l.upper = ldl_le_p(ptr + 4);
|
|
||||||
return u.d;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stfq_le_p(void *ptr, float64 v)
|
|
||||||
{
|
|
||||||
CPU_DoubleU u;
|
|
||||||
u.d = v;
|
|
||||||
stl_le_p(ptr, u.l.lower);
|
|
||||||
stl_le_p(ptr + 4, u.l.upper);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static inline int lduw_le_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return *(uint16_t *)ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int ldsw_le_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return *(int16_t *)ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int ldl_le_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return *(uint32_t *)ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t ldq_le_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return *(uint64_t *)ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stw_le_p(void *ptr, int v)
|
|
||||||
{
|
|
||||||
*(uint16_t *)ptr = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stl_le_p(void *ptr, int v)
|
|
||||||
{
|
|
||||||
*(uint32_t *)ptr = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stq_le_p(void *ptr, uint64_t v)
|
|
||||||
{
|
|
||||||
*(uint64_t *)ptr = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* float access */
|
|
||||||
|
|
||||||
static inline float32 ldfl_le_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return *(float32 *)ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline float64 ldfq_le_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return *(float64 *)ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stfl_le_p(void *ptr, float32 v)
|
|
||||||
{
|
|
||||||
*(float32 *)ptr = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stfq_le_p(void *ptr, float64 v)
|
|
||||||
{
|
|
||||||
*(float64 *)ptr = v;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
|
|
||||||
|
|
||||||
static inline int lduw_be_p(const void *ptr)
|
|
||||||
{
|
|
||||||
#if defined(__i386__)
|
|
||||||
int val;
|
|
||||||
asm volatile ("movzwl %1, %0\n"
|
|
||||||
"xchgb %b0, %h0\n"
|
|
||||||
: "=q" (val)
|
|
||||||
: "m" (*(uint16_t *)ptr));
|
|
||||||
return val;
|
|
||||||
#else
|
|
||||||
const uint8_t *b = ptr;
|
|
||||||
return ((b[0] << 8) | b[1]);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int ldsw_be_p(const void *ptr)
|
|
||||||
{
|
|
||||||
#if defined(__i386__)
|
|
||||||
int val;
|
|
||||||
asm volatile ("movzwl %1, %0\n"
|
|
||||||
"xchgb %b0, %h0\n"
|
|
||||||
: "=q" (val)
|
|
||||||
: "m" (*(uint16_t *)ptr));
|
|
||||||
return (int16_t)val;
|
|
||||||
#else
|
|
||||||
const uint8_t *b = ptr;
|
|
||||||
return (int16_t)((b[0] << 8) | b[1]);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int ldl_be_p(const void *ptr)
|
|
||||||
{
|
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
|
||||||
int val;
|
|
||||||
asm volatile ("movl %1, %0\n"
|
|
||||||
"bswap %0\n"
|
|
||||||
: "=r" (val)
|
|
||||||
: "m" (*(uint32_t *)ptr));
|
|
||||||
return val;
|
|
||||||
#else
|
|
||||||
const uint8_t *b = ptr;
|
|
||||||
return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t ldq_be_p(const void *ptr)
|
|
||||||
{
|
|
||||||
uint32_t a,b;
|
|
||||||
a = ldl_be_p(ptr);
|
|
||||||
b = ldl_be_p((uint8_t *)ptr + 4);
|
|
||||||
return (((uint64_t)a<<32)|b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stw_be_p(void *ptr, int v)
|
|
||||||
{
|
|
||||||
#if defined(__i386__)
|
|
||||||
asm volatile ("xchgb %b0, %h0\n"
|
|
||||||
"movw %w0, %1\n"
|
|
||||||
: "=q" (v)
|
|
||||||
: "m" (*(uint16_t *)ptr), "0" (v));
|
|
||||||
#else
|
|
||||||
uint8_t *d = (uint8_t *) ptr;
|
|
||||||
d[0] = v >> 8;
|
|
||||||
d[1] = v;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stl_be_p(void *ptr, int v)
|
|
||||||
{
|
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
|
||||||
asm volatile ("bswap %0\n"
|
|
||||||
"movl %0, %1\n"
|
|
||||||
: "=r" (v)
|
|
||||||
: "m" (*(uint32_t *)ptr), "0" (v));
|
|
||||||
#else
|
|
||||||
uint8_t *d = (uint8_t *) ptr;
|
|
||||||
d[0] = v >> 24;
|
|
||||||
d[1] = v >> 16;
|
|
||||||
d[2] = v >> 8;
|
|
||||||
d[3] = v;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stq_be_p(void *ptr, uint64_t v)
|
|
||||||
{
|
|
||||||
stl_be_p(ptr, v >> 32);
|
|
||||||
stl_be_p((uint8_t *)ptr + 4, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* float access */
|
|
||||||
|
|
||||||
static inline float32 ldfl_be_p(const void *ptr)
|
|
||||||
{
|
|
||||||
union {
|
|
||||||
float32 f;
|
|
||||||
uint32_t i;
|
|
||||||
} u;
|
|
||||||
u.i = ldl_be_p(ptr);
|
|
||||||
return u.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stfl_be_p(void *ptr, float32 v)
|
|
||||||
{
|
|
||||||
union {
|
|
||||||
float32 f;
|
|
||||||
uint32_t i;
|
|
||||||
} u;
|
|
||||||
u.f = v;
|
|
||||||
stl_be_p(ptr, u.i);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline float64 ldfq_be_p(const void *ptr)
|
|
||||||
{
|
|
||||||
CPU_DoubleU u;
|
|
||||||
u.l.upper = ldl_be_p(ptr);
|
|
||||||
u.l.lower = ldl_be_p((uint8_t *)ptr + 4);
|
|
||||||
return u.d;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stfq_be_p(void *ptr, float64 v)
|
|
||||||
{
|
|
||||||
CPU_DoubleU u;
|
|
||||||
u.d = v;
|
|
||||||
stl_be_p(ptr, u.l.upper);
|
|
||||||
stl_be_p((uint8_t *)ptr + 4, u.l.lower);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static inline int lduw_be_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return *(uint16_t *)ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int ldsw_be_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return *(int16_t *)ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int ldl_be_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return *(uint32_t *)ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t ldq_be_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return *(uint64_t *)ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stw_be_p(void *ptr, int v)
|
|
||||||
{
|
|
||||||
*(uint16_t *)ptr = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stl_be_p(void *ptr, int v)
|
|
||||||
{
|
|
||||||
*(uint32_t *)ptr = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stq_be_p(void *ptr, uint64_t v)
|
|
||||||
{
|
|
||||||
*(uint64_t *)ptr = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* float access */
|
|
||||||
|
|
||||||
static inline float32 ldfl_be_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return *(float32 *)ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline float64 ldfq_be_p(const void *ptr)
|
|
||||||
{
|
|
||||||
return *(float64 *)ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stfl_be_p(void *ptr, float32 v)
|
|
||||||
{
|
|
||||||
*(float32 *)ptr = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void stfq_be_p(void *ptr, float64 v)
|
|
||||||
{
|
|
||||||
*(float64 *)ptr = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* target CPU memory access functions */
|
|
||||||
#if defined(TARGET_WORDS_BIGENDIAN)
|
#if defined(TARGET_WORDS_BIGENDIAN)
|
||||||
#define lduw_p(p) lduw_be_p(p)
|
#define lduw_p(p) lduw_be_p(p)
|
||||||
#define ldsw_p(p) ldsw_be_p(p)
|
#define ldsw_p(p) ldsw_be_p(p)
|
||||||
|
Loading…
Reference in New Issue
Block a user