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) | ||||
| 
 | ||||
| QEMU_CFLAGS+=-I.. -I$(SRC_PATH)/fpu | ||||
| QEMU_CFLAGS+=-I.. | ||||
| 
 | ||||
| include $(SRC_PATH)/Makefile.objs | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										474
									
								
								bswap.h
									
									
									
									
									
								
							
							
						
						
									
										474
									
								
								bswap.h
									
									
									
									
									
								
							| @ -11,6 +11,8 @@ | ||||
| #include <machine/bswap.h> | ||||
| #else | ||||
| 
 | ||||
| #include "softfloat.h" | ||||
| 
 | ||||
| #ifdef CONFIG_BYTESWAP_H | ||||
| #include <byteswap.h> | ||||
| #else | ||||
| @ -237,4 +239,476 @@ static inline uint32_t qemu_bswap_len(uint32_t value, int 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 */ | ||||
|  | ||||
							
								
								
									
										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="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE $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" | ||||
| 
 | ||||
| # make source path absolute | ||||
| @ -3374,7 +3374,6 @@ else | ||||
|   includes="-I\$(SRC_PATH)/tcg/\$(ARCH) $includes" | ||||
| fi | ||||
| includes="-I\$(SRC_PATH)/tcg $includes" | ||||
| includes="-I\$(SRC_PATH)/fpu $includes" | ||||
| 
 | ||||
| if test "$target_user_only" = "yes" ; then | ||||
|     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 | ||||
|  */ | ||||
| 
 | ||||
| #include "softfloat.h" | ||||
| 
 | ||||
| #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) | ||||
| #define BSWAP_NEEDED | ||||
| #endif | ||||
| @ -114,64 +112,6 @@ static inline void tswap64s(uint64_t *s) | ||||
| #define bswaptls(s) bswap64s(s) | ||||
| #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 */ | ||||
| 
 | ||||
| /*
 | ||||
| @ -207,392 +147,8 @@ typedef union { | ||||
|  *   user   : user 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) | ||||
| { | ||||
|     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 */ | ||||
| /* target-endianness CPU memory access functions */ | ||||
| #if defined(TARGET_WORDS_BIGENDIAN) | ||||
| #define lduw_p(p) lduw_be_p(p) | ||||
| #define ldsw_p(p) ldsw_be_p(p) | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Paolo Bonzini
						Paolo Bonzini