Commit 2f4a40e56972be8088faa78cfe2120a4a0026b2d
1 parent
c3e36823
Prevent cpsr_write/_read be put out of line in op.o (fixes a segfault on some platforms).
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3633 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
45 additions
and
44 deletions
slirp/misc.c
target-arm/cpu.h
| ... | ... | @@ -248,16 +248,9 @@ void cpu_unlock(void); |
| 248 | 248 | #define CPSR_EXEC (CPSR_T | CPSR_IT | CPSR_J) |
| 249 | 249 | |
| 250 | 250 | /* Return the current CPSR value. */ |
| 251 | -static inline uint32_t cpsr_read(CPUARMState *env) | |
| 252 | -{ | |
| 253 | - int ZF; | |
| 254 | - ZF = (env->NZF == 0); | |
| 255 | - return env->uncached_cpsr | (env->NZF & 0x80000000) | (ZF << 30) | | |
| 256 | - (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27) | |
| 257 | - | (env->thumb << 5) | ((env->condexec_bits & 3) << 25) | |
| 258 | - | ((env->condexec_bits & 0xfc) << 8) | |
| 259 | - | (env->GE << 16); | |
| 260 | -} | |
| 251 | +uint32_t cpsr_read(CPUARMState *env); | |
| 252 | +/* Set the CPSR. Note that some bits of mask must be all-set or all-clear. */ | |
| 253 | +void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask); | |
| 261 | 254 | |
| 262 | 255 | /* Return the current xPSR value. */ |
| 263 | 256 | static inline uint32_t xpsr_read(CPUARMState *env) |
| ... | ... | @@ -271,38 +264,6 @@ static inline uint32_t xpsr_read(CPUARMState *env) |
| 271 | 264 | | env->v7m.exception; |
| 272 | 265 | } |
| 273 | 266 | |
| 274 | -/* Set the CPSR. Note that some bits of mask must be all-set or all-clear. */ | |
| 275 | -static inline void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) | |
| 276 | -{ | |
| 277 | - /* NOTE: N = 1 and Z = 1 cannot be stored currently */ | |
| 278 | - if (mask & CPSR_NZCV) { | |
| 279 | - env->NZF = (val & 0xc0000000) ^ 0x40000000; | |
| 280 | - env->CF = (val >> 29) & 1; | |
| 281 | - env->VF = (val << 3) & 0x80000000; | |
| 282 | - } | |
| 283 | - if (mask & CPSR_Q) | |
| 284 | - env->QF = ((val & CPSR_Q) != 0); | |
| 285 | - if (mask & CPSR_T) | |
| 286 | - env->thumb = ((val & CPSR_T) != 0); | |
| 287 | - if (mask & CPSR_IT_0_1) { | |
| 288 | - env->condexec_bits &= ~3; | |
| 289 | - env->condexec_bits |= (val >> 25) & 3; | |
| 290 | - } | |
| 291 | - if (mask & CPSR_IT_2_7) { | |
| 292 | - env->condexec_bits &= 3; | |
| 293 | - env->condexec_bits |= (val >> 8) & 0xfc; | |
| 294 | - } | |
| 295 | - if (mask & CPSR_GE) { | |
| 296 | - env->GE = (val >> 16) & 0xf; | |
| 297 | - } | |
| 298 | - | |
| 299 | - if ((env->uncached_cpsr ^ val) & mask & CPSR_M) { | |
| 300 | - switch_mode(env, val & CPSR_M); | |
| 301 | - } | |
| 302 | - mask &= ~CACHED_CPSR_BITS; | |
| 303 | - env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask); | |
| 304 | -} | |
| 305 | - | |
| 306 | 267 | /* Set the xPSR. Note that some bits of mask must be all-set or all-clear. */ |
| 307 | 268 | static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) |
| 308 | 269 | { | ... | ... |
target-arm/helper.c
| ... | ... | @@ -272,6 +272,48 @@ uint32_t helper_neon_mul_p8(uint32_t op1, uint32_t op2) |
| 272 | 272 | return result; |
| 273 | 273 | } |
| 274 | 274 | |
| 275 | +uint32_t cpsr_read(CPUARMState *env) | |
| 276 | +{ | |
| 277 | + int ZF; | |
| 278 | + ZF = (env->NZF == 0); | |
| 279 | + return env->uncached_cpsr | (env->NZF & 0x80000000) | (ZF << 30) | | |
| 280 | + (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27) | |
| 281 | + | (env->thumb << 5) | ((env->condexec_bits & 3) << 25) | |
| 282 | + | ((env->condexec_bits & 0xfc) << 8) | |
| 283 | + | (env->GE << 16); | |
| 284 | +} | |
| 285 | + | |
| 286 | +void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) | |
| 287 | +{ | |
| 288 | + /* NOTE: N = 1 and Z = 1 cannot be stored currently */ | |
| 289 | + if (mask & CPSR_NZCV) { | |
| 290 | + env->NZF = (val & 0xc0000000) ^ 0x40000000; | |
| 291 | + env->CF = (val >> 29) & 1; | |
| 292 | + env->VF = (val << 3) & 0x80000000; | |
| 293 | + } | |
| 294 | + if (mask & CPSR_Q) | |
| 295 | + env->QF = ((val & CPSR_Q) != 0); | |
| 296 | + if (mask & CPSR_T) | |
| 297 | + env->thumb = ((val & CPSR_T) != 0); | |
| 298 | + if (mask & CPSR_IT_0_1) { | |
| 299 | + env->condexec_bits &= ~3; | |
| 300 | + env->condexec_bits |= (val >> 25) & 3; | |
| 301 | + } | |
| 302 | + if (mask & CPSR_IT_2_7) { | |
| 303 | + env->condexec_bits &= 3; | |
| 304 | + env->condexec_bits |= (val >> 8) & 0xfc; | |
| 305 | + } | |
| 306 | + if (mask & CPSR_GE) { | |
| 307 | + env->GE = (val >> 16) & 0xf; | |
| 308 | + } | |
| 309 | + | |
| 310 | + if ((env->uncached_cpsr ^ val) & mask & CPSR_M) { | |
| 311 | + switch_mode(env, val & CPSR_M); | |
| 312 | + } | |
| 313 | + mask &= ~CACHED_CPSR_BITS; | |
| 314 | + env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask); | |
| 315 | +} | |
| 316 | + | |
| 275 | 317 | #if defined(CONFIG_USER_ONLY) |
| 276 | 318 | |
| 277 | 319 | void do_interrupt (CPUState *env) | ... | ... |