Commit 0ac4bd56a8baf235c136c84b338616d47ce01689

Authored by bellard
1 parent 3811a291

float access fixes


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@489 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 86 additions and 42 deletions
cpu-all.h
... ... @@ -20,6 +20,40 @@
20 20 #ifndef CPU_ALL_H
21 21 #define CPU_ALL_H
22 22  
  23 +#if defined(__arm__) || defined(__sparc__)
  24 +#define WORDS_ALIGNED
  25 +#endif
  26 +
  27 +/* some important defines:
  28 + *
  29 + * WORDS_ALIGNED : if defined, the host cpu can only make word aligned
  30 + * memory accesses.
  31 + *
  32 + * WORDS_BIGENDIAN : if defined, the host cpu is big endian and
  33 + * otherwise little endian.
  34 + *
  35 + * (TARGET_WORDS_ALIGNED : same for target cpu (not supported yet))
  36 + *
  37 + * TARGET_WORDS_BIGENDIAN : same for target cpu
  38 + */
  39 +
  40 +/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */
  41 +typedef union {
  42 + double d;
  43 +#if !defined(WORDS_BIGENDIAN) && !defined(__arm__)
  44 + struct {
  45 + uint32_t lower;
  46 + uint32_t upper;
  47 + } l;
  48 +#else
  49 + struct {
  50 + uint32_t upper;
  51 + uint32_t lower;
  52 + } l;
  53 +#endif
  54 + uint64_t ll;
  55 +} CPU_DoubleU;
  56 +
23 57 /* CPU memory access without any memory or io remapping */
24 58  
25 59 static inline int ldub_raw(void *ptr)
... ... @@ -40,7 +74,7 @@ static inline void stb_raw(void *ptr, int v)
40 74 /* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the
41 75 kernel handles unaligned load/stores may give better results, but
42 76 it is a system wide setting : bad */
43   -#if defined(WORDS_BIGENDIAN) || defined(__arm__)
  77 +#if !defined(TARGET_WORDS_BIGENDIAN) && (defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED))
44 78  
45 79 /* conservative code for little endian unaligned accesses */
46 80 static inline int lduw_raw(void *ptr)
... ... @@ -141,55 +175,23 @@ static inline void stfl_raw(void *ptr, float v)
141 175 stl_raw(ptr, u.i);
142 176 }
143 177  
144   -
145   -#if defined(__arm__) && !defined(WORDS_BIGENDIAN)
146   -
147   -/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */
148 178 static inline double ldfq_raw(void *ptr)
149 179 {
150   - union {
151   - double d;
152   - uint32_t tab[2];
153   - } u;
154   - u.tab[1] = ldl_raw(ptr);
155   - u.tab[0] = ldl_raw(ptr + 4);
  180 + CPU_DoubleU u;
  181 + u.l.lower = ldl_raw(ptr);
  182 + u.l.upper = ldl_raw(ptr + 4);
156 183 return u.d;
157 184 }
158 185  
159 186 static inline void stfq_raw(void *ptr, double v)
160 187 {
161   - union {
162   - double d;
163   - uint32_t tab[2];
164   - } u;
  188 + CPU_DoubleU u;
165 189 u.d = v;
166   - stl_raw(ptr, u.tab[1]);
167   - stl_raw(ptr + 4, u.tab[0]);
  190 + stl_raw(ptr, u.l.lower);
  191 + stl_raw(ptr + 4, u.l.upper);
168 192 }
169 193  
170   -#else
171   -static inline double ldfq_raw(void *ptr)
172   -{
173   - union {
174   - double d;
175   - uint64_t i;
176   - } u;
177   - u.i = ldq_raw(ptr);
178   - return u.d;
179   -}
180   -
181   -static inline void stfq_raw(void *ptr, double v)
182   -{
183   - union {
184   - double d;
185   - uint64_t i;
186   - } u;
187   - u.d = v;
188   - stq_raw(ptr, u.i);
189   -}
190   -#endif
191   -
192   -#elif defined(TARGET_WORDS_BIGENDIAN) && !defined(WORDS_BIGENDIAN)
  194 +#elif defined(TARGET_WORDS_BIGENDIAN) && (!defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED))
193 195  
194 196 static inline int lduw_raw(void *ptr)
195 197 {
... ... @@ -235,8 +237,46 @@ static inline void stl_raw(void *ptr, int v)
235 237  
236 238 static inline void stq_raw(void *ptr, uint64_t v)
237 239 {
238   - stl_raw(ptr, v);
239   - stl_raw(ptr+4, v >> 32);
  240 + stl_raw(ptr, v >> 32);
  241 + stl_raw(ptr + 4, v);
  242 +}
  243 +
  244 +/* float access */
  245 +
  246 +static inline float ldfl_raw(void *ptr)
  247 +{
  248 + union {
  249 + float f;
  250 + uint32_t i;
  251 + } u;
  252 + u.i = ldl_raw(ptr);
  253 + return u.f;
  254 +}
  255 +
  256 +static inline void stfl_raw(void *ptr, float v)
  257 +{
  258 + union {
  259 + float f;
  260 + uint32_t i;
  261 + } u;
  262 + u.f = v;
  263 + stl_raw(ptr, u.i);
  264 +}
  265 +
  266 +static inline double ldfq_raw(void *ptr)
  267 +{
  268 + CPU_DoubleU u;
  269 + u.l.upper = ldl_raw(ptr);
  270 + u.l.lower = ldl_raw(ptr + 4);
  271 + return u.d;
  272 +}
  273 +
  274 +static inline void stfq_raw(void *ptr, double v)
  275 +{
  276 + CPU_DoubleU u;
  277 + u.d = v;
  278 + stl_raw(ptr, u.l.upper);
  279 + stl_raw(ptr + 4, u.l.lower);
240 280 }
241 281  
242 282 #else
... ... @@ -330,10 +370,14 @@ static inline void stfq_raw(void *ptr, double v)
330 370 #define lduw_kernel(p) lduw_raw(p)
331 371 #define ldsw_kernel(p) ldsw_raw(p)
332 372 #define ldl_kernel(p) ldl_raw(p)
  373 +#define ldfl_kernel(p) ldfl_raw(p)
  374 +#define ldfq_kernel(p) ldfq_raw(p)
333 375 #define stb_kernel(p, v) stb_raw(p, v)
334 376 #define stw_kernel(p, v) stw_raw(p, v)
335 377 #define stl_kernel(p, v) stl_raw(p, v)
336 378 #define stq_kernel(p, v) stq_raw(p, v)
  379 +#define stfl_kernel(p, v) stfl_raw(p, v)
  380 +#define stfq_kernel(p, vt) stfq_raw(p, v)
337 381  
338 382 #endif /* defined(CONFIG_USER_ONLY) */
339 383  
... ...