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,6 +20,40 @@
20 #ifndef CPU_ALL_H 20 #ifndef CPU_ALL_H
21 #define CPU_ALL_H 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 /* CPU memory access without any memory or io remapping */ 57 /* CPU memory access without any memory or io remapping */
24 58
25 static inline int ldub_raw(void *ptr) 59 static inline int ldub_raw(void *ptr)
@@ -40,7 +74,7 @@ static inline void stb_raw(void *ptr, int v) @@ -40,7 +74,7 @@ static inline void stb_raw(void *ptr, int v)
40 /* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the 74 /* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the
41 kernel handles unaligned load/stores may give better results, but 75 kernel handles unaligned load/stores may give better results, but
42 it is a system wide setting : bad */ 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 /* conservative code for little endian unaligned accesses */ 79 /* conservative code for little endian unaligned accesses */
46 static inline int lduw_raw(void *ptr) 80 static inline int lduw_raw(void *ptr)
@@ -141,55 +175,23 @@ static inline void stfl_raw(void *ptr, float v) @@ -141,55 +175,23 @@ static inline void stfl_raw(void *ptr, float v)
141 stl_raw(ptr, u.i); 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 static inline double ldfq_raw(void *ptr) 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 return u.d; 183 return u.d;
157 } 184 }
158 185
159 static inline void stfq_raw(void *ptr, double v) 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 u.d = v; 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 static inline int lduw_raw(void *ptr) 196 static inline int lduw_raw(void *ptr)
195 { 197 {
@@ -235,8 +237,46 @@ static inline void stl_raw(void *ptr, int v) @@ -235,8 +237,46 @@ static inline void stl_raw(void *ptr, int v)
235 237
236 static inline void stq_raw(void *ptr, uint64_t v) 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 #else 282 #else
@@ -330,10 +370,14 @@ static inline void stfq_raw(void *ptr, double v) @@ -330,10 +370,14 @@ static inline void stfq_raw(void *ptr, double v)
330 #define lduw_kernel(p) lduw_raw(p) 370 #define lduw_kernel(p) lduw_raw(p)
331 #define ldsw_kernel(p) ldsw_raw(p) 371 #define ldsw_kernel(p) ldsw_raw(p)
332 #define ldl_kernel(p) ldl_raw(p) 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 #define stb_kernel(p, v) stb_raw(p, v) 375 #define stb_kernel(p, v) stb_raw(p, v)
334 #define stw_kernel(p, v) stw_raw(p, v) 376 #define stw_kernel(p, v) stw_raw(p, v)
335 #define stl_kernel(p, v) stl_raw(p, v) 377 #define stl_kernel(p, v) stl_raw(p, v)
336 #define stq_kernel(p, v) stq_raw(p, v) 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 #endif /* defined(CONFIG_USER_ONLY) */ 382 #endif /* defined(CONFIG_USER_ONLY) */
339 383