summaryrefslogtreecommitdiff
path: root/target-arm
diff options
context:
space:
mode:
authorbalrog <balrog@c046a42c-6fe2-441c-8c8c-71466251a162>2007-11-13 01:50:15 +0000
committerbalrog <balrog@c046a42c-6fe2-441c-8c8c-71466251a162>2007-11-13 01:50:15 +0000
commit2f4a40e56972be8088faa78cfe2120a4a0026b2d (patch)
tree548e36ee954c49b003c4d620d693c85272b9c2fa /target-arm
parentc3e3682388f422921b2ae13264d35859981da752 (diff)
downloadqemu-2f4a40e56972be8088faa78cfe2120a4a0026b2d.zip
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
Diffstat (limited to 'target-arm')
-rw-r--r--target-arm/cpu.h45
-rw-r--r--target-arm/helper.c42
2 files changed, 45 insertions, 42 deletions
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 59b96963b1..b284a21699 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -248,16 +248,9 @@ void cpu_unlock(void);
#define CPSR_EXEC (CPSR_T | CPSR_IT | CPSR_J)
/* Return the current CPSR value. */
-static inline uint32_t cpsr_read(CPUARMState *env)
-{
- int ZF;
- ZF = (env->NZF == 0);
- return env->uncached_cpsr | (env->NZF & 0x80000000) | (ZF << 30) |
- (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
- | (env->thumb << 5) | ((env->condexec_bits & 3) << 25)
- | ((env->condexec_bits & 0xfc) << 8)
- | (env->GE << 16);
-}
+uint32_t cpsr_read(CPUARMState *env);
+/* Set the CPSR. Note that some bits of mask must be all-set or all-clear. */
+void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask);
/* Return the current xPSR value. */
static inline uint32_t xpsr_read(CPUARMState *env)
@@ -271,38 +264,6 @@ static inline uint32_t xpsr_read(CPUARMState *env)
| env->v7m.exception;
}
-/* Set the CPSR. Note that some bits of mask must be all-set or all-clear. */
-static inline void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
-{
- /* NOTE: N = 1 and Z = 1 cannot be stored currently */
- if (mask & CPSR_NZCV) {
- env->NZF = (val & 0xc0000000) ^ 0x40000000;
- env->CF = (val >> 29) & 1;
- env->VF = (val << 3) & 0x80000000;
- }
- if (mask & CPSR_Q)
- env->QF = ((val & CPSR_Q) != 0);
- if (mask & CPSR_T)
- env->thumb = ((val & CPSR_T) != 0);
- if (mask & CPSR_IT_0_1) {
- env->condexec_bits &= ~3;
- env->condexec_bits |= (val >> 25) & 3;
- }
- if (mask & CPSR_IT_2_7) {
- env->condexec_bits &= 3;
- env->condexec_bits |= (val >> 8) & 0xfc;
- }
- if (mask & CPSR_GE) {
- env->GE = (val >> 16) & 0xf;
- }
-
- if ((env->uncached_cpsr ^ val) & mask & CPSR_M) {
- switch_mode(env, val & CPSR_M);
- }
- mask &= ~CACHED_CPSR_BITS;
- env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask);
-}
-
/* Set the xPSR. Note that some bits of mask must be all-set or all-clear. */
static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
{
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 69752564d1..038025dac0 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -272,6 +272,48 @@ uint32_t helper_neon_mul_p8(uint32_t op1, uint32_t op2)
return result;
}
+uint32_t cpsr_read(CPUARMState *env)
+{
+ int ZF;
+ ZF = (env->NZF == 0);
+ return env->uncached_cpsr | (env->NZF & 0x80000000) | (ZF << 30) |
+ (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
+ | (env->thumb << 5) | ((env->condexec_bits & 3) << 25)
+ | ((env->condexec_bits & 0xfc) << 8)
+ | (env->GE << 16);
+}
+
+void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
+{
+ /* NOTE: N = 1 and Z = 1 cannot be stored currently */
+ if (mask & CPSR_NZCV) {
+ env->NZF = (val & 0xc0000000) ^ 0x40000000;
+ env->CF = (val >> 29) & 1;
+ env->VF = (val << 3) & 0x80000000;
+ }
+ if (mask & CPSR_Q)
+ env->QF = ((val & CPSR_Q) != 0);
+ if (mask & CPSR_T)
+ env->thumb = ((val & CPSR_T) != 0);
+ if (mask & CPSR_IT_0_1) {
+ env->condexec_bits &= ~3;
+ env->condexec_bits |= (val >> 25) & 3;
+ }
+ if (mask & CPSR_IT_2_7) {
+ env->condexec_bits &= 3;
+ env->condexec_bits |= (val >> 8) & 0xfc;
+ }
+ if (mask & CPSR_GE) {
+ env->GE = (val >> 16) & 0xf;
+ }
+
+ if ((env->uncached_cpsr ^ val) & mask & CPSR_M) {
+ switch_mode(env, val & CPSR_M);
+ }
+ mask &= ~CACHED_CPSR_BITS;
+ env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask);
+}
+
#if defined(CONFIG_USER_ONLY)
void do_interrupt (CPUState *env)