Commit a95c67907cce5b03269581b77f014ec51b98da36
1 parent
0f533160
arm support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@221 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
61 additions
and
8 deletions
cpu-i386.h
| @@ -238,7 +238,10 @@ static inline void stb(void *ptr, int v) | @@ -238,7 +238,10 @@ static inline void stb(void *ptr, int v) | ||
| 238 | *(uint8_t *)ptr = v; | 238 | *(uint8_t *)ptr = v; |
| 239 | } | 239 | } |
| 240 | 240 | ||
| 241 | -#ifdef WORDS_BIGENDIAN | 241 | +/* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the |
| 242 | + kernel handles unaligned load/stores may give better results, but | ||
| 243 | + it is a system wide setting : bad */ | ||
| 244 | +#if defined(WORDS_BIGENDIAN) || defined(__arm__) | ||
| 242 | 245 | ||
| 243 | /* conservative code for little endian unaligned accesses */ | 246 | /* conservative code for little endian unaligned accesses */ |
| 244 | static inline int lduw(void *ptr) | 247 | static inline int lduw(void *ptr) |
| @@ -329,24 +332,50 @@ static inline float ldfl(void *ptr) | @@ -329,24 +332,50 @@ static inline float ldfl(void *ptr) | ||
| 329 | return u.f; | 332 | return u.f; |
| 330 | } | 333 | } |
| 331 | 334 | ||
| 335 | +static inline void stfl(void *ptr, float v) | ||
| 336 | +{ | ||
| 337 | + union { | ||
| 338 | + float f; | ||
| 339 | + uint32_t i; | ||
| 340 | + } u; | ||
| 341 | + u.f = v; | ||
| 342 | + stl(ptr, u.i); | ||
| 343 | +} | ||
| 344 | + | ||
| 345 | +#if defined(__arm__) && !defined(WORDS_BIGENDIAN) | ||
| 346 | + | ||
| 347 | +/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */ | ||
| 332 | static inline double ldfq(void *ptr) | 348 | static inline double ldfq(void *ptr) |
| 333 | { | 349 | { |
| 334 | union { | 350 | union { |
| 335 | double d; | 351 | double d; |
| 336 | - uint64_t i; | 352 | + uint32_t tab[2]; |
| 337 | } u; | 353 | } u; |
| 338 | - u.i = ldq(ptr); | 354 | + u.tab[1] = ldl(ptr); |
| 355 | + u.tab[0] = ldl(ptr + 4); | ||
| 339 | return u.d; | 356 | return u.d; |
| 340 | } | 357 | } |
| 341 | 358 | ||
| 342 | -static inline void stfl(void *ptr, float v) | 359 | +static inline void stfq(void *ptr, double v) |
| 343 | { | 360 | { |
| 344 | union { | 361 | union { |
| 345 | - float f; | ||
| 346 | - uint32_t i; | 362 | + double d; |
| 363 | + uint32_t tab[2]; | ||
| 347 | } u; | 364 | } u; |
| 348 | - u.f = v; | ||
| 349 | - stl(ptr, u.i); | 365 | + u.d = v; |
| 366 | + stl(ptr, u.tab[1]); | ||
| 367 | + stl(ptr + 4, u.tab[0]); | ||
| 368 | +} | ||
| 369 | + | ||
| 370 | +#else | ||
| 371 | +static inline double ldfq(void *ptr) | ||
| 372 | +{ | ||
| 373 | + union { | ||
| 374 | + double d; | ||
| 375 | + uint64_t i; | ||
| 376 | + } u; | ||
| 377 | + u.i = ldq(ptr); | ||
| 378 | + return u.d; | ||
| 350 | } | 379 | } |
| 351 | 380 | ||
| 352 | static inline void stfq(void *ptr, double v) | 381 | static inline void stfq(void *ptr, double v) |
| @@ -358,6 +387,7 @@ static inline void stfq(void *ptr, double v) | @@ -358,6 +387,7 @@ static inline void stfq(void *ptr, double v) | ||
| 358 | u.d = v; | 387 | u.d = v; |
| 359 | stq(ptr, u.i); | 388 | stq(ptr, u.i); |
| 360 | } | 389 | } |
| 390 | +#endif | ||
| 361 | 391 | ||
| 362 | #else | 392 | #else |
| 363 | 393 |
exec.h
| @@ -246,6 +246,18 @@ static inline int testandset (int *p) | @@ -246,6 +246,18 @@ static inline int testandset (int *p) | ||
| 246 | } | 246 | } |
| 247 | #endif | 247 | #endif |
| 248 | 248 | ||
| 249 | +#ifdef __arm__ | ||
| 250 | +static inline int testandset (int *spinlock) | ||
| 251 | +{ | ||
| 252 | + register unsigned int ret; | ||
| 253 | + __asm__ __volatile__("swp %0, %1, [%2]" | ||
| 254 | + : "=r"(ret) | ||
| 255 | + : "0"(1), "r"(spinlock)); | ||
| 256 | + | ||
| 257 | + return ret; | ||
| 258 | +} | ||
| 259 | +#endif | ||
| 260 | + | ||
| 249 | typedef int spinlock_t; | 261 | typedef int spinlock_t; |
| 250 | 262 | ||
| 251 | #define SPIN_LOCK_UNLOCKED 0 | 263 | #define SPIN_LOCK_UNLOCKED 0 |
translate-i386.c
| @@ -104,6 +104,16 @@ static void inline flush_icache_range(unsigned long start, unsigned long stop) | @@ -104,6 +104,16 @@ static void inline flush_icache_range(unsigned long start, unsigned long stop) | ||
| 104 | 104 | ||
| 105 | #endif | 105 | #endif |
| 106 | 106 | ||
| 107 | +#ifdef __arm__ | ||
| 108 | +static inline void flush_icache_range(unsigned long start, unsigned long stop) | ||
| 109 | +{ | ||
| 110 | + register unsigned long _beg __asm ("a1") = start; | ||
| 111 | + register unsigned long _end __asm ("a2") = stop; | ||
| 112 | + register unsigned long _flg __asm ("a3") = 0; | ||
| 113 | + __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg)); | ||
| 114 | +} | ||
| 115 | +#endif | ||
| 116 | + | ||
| 107 | extern FILE *logfile; | 117 | extern FILE *logfile; |
| 108 | extern int loglevel; | 118 | extern int loglevel; |
| 109 | 119 | ||
| @@ -166,6 +176,7 @@ enum { | @@ -166,6 +176,7 @@ enum { | ||
| 166 | NB_OPS, | 176 | NB_OPS, |
| 167 | }; | 177 | }; |
| 168 | 178 | ||
| 179 | +#include "dyngen.h" | ||
| 169 | #include "op-i386.h" | 180 | #include "op-i386.h" |
| 170 | 181 | ||
| 171 | /* operand size */ | 182 | /* operand size */ |