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 | 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 | 246 | /* conservative code for little endian unaligned accesses */ |
| 244 | 247 | static inline int lduw(void *ptr) |
| ... | ... | @@ -329,24 +332,50 @@ static inline float ldfl(void *ptr) |
| 329 | 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 | 348 | static inline double ldfq(void *ptr) |
| 333 | 349 | { |
| 334 | 350 | union { |
| 335 | 351 | double d; |
| 336 | - uint64_t i; | |
| 352 | + uint32_t tab[2]; | |
| 337 | 353 | } u; |
| 338 | - u.i = ldq(ptr); | |
| 354 | + u.tab[1] = ldl(ptr); | |
| 355 | + u.tab[0] = ldl(ptr + 4); | |
| 339 | 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 | 361 | union { |
| 345 | - float f; | |
| 346 | - uint32_t i; | |
| 362 | + double d; | |
| 363 | + uint32_t tab[2]; | |
| 347 | 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 | 381 | static inline void stfq(void *ptr, double v) |
| ... | ... | @@ -358,6 +387,7 @@ static inline void stfq(void *ptr, double v) |
| 358 | 387 | u.d = v; |
| 359 | 388 | stq(ptr, u.i); |
| 360 | 389 | } |
| 390 | +#endif | |
| 361 | 391 | |
| 362 | 392 | #else |
| 363 | 393 | ... | ... |
exec.h
| ... | ... | @@ -246,6 +246,18 @@ static inline int testandset (int *p) |
| 246 | 246 | } |
| 247 | 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 | 261 | typedef int spinlock_t; |
| 250 | 262 | |
| 251 | 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 | 104 | |
| 105 | 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 | 117 | extern FILE *logfile; |
| 108 | 118 | extern int loglevel; |
| 109 | 119 | |
| ... | ... | @@ -166,6 +176,7 @@ enum { |
| 166 | 176 | NB_OPS, |
| 167 | 177 | }; |
| 168 | 178 | |
| 179 | +#include "dyngen.h" | |
| 169 | 180 | #include "op-i386.h" |
| 170 | 181 | |
| 171 | 182 | /* operand size */ | ... | ... |