[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [4156] ARM N=Z=1 flag fix.
From: |
Paul Brook |
Subject: |
[Qemu-devel] [4156] ARM N=Z=1 flag fix. |
Date: |
Tue, 01 Apr 2008 17:19:12 +0000 |
Revision: 4156
http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4156
Author: pbrook
Date: 2008-04-01 17:19:11 +0000 (Tue, 01 Apr 2008)
Log Message:
-----------
ARM N=Z=1 flag fix.
Modified Paths:
--------------
trunk/target-arm/cpu.h
trunk/target-arm/helper.c
trunk/target-arm/op_helper.c
trunk/target-arm/translate.c
Modified: trunk/target-arm/cpu.h
===================================================================
--- trunk/target-arm/cpu.h 2008-03-31 23:41:24 UTC (rev 4155)
+++ trunk/target-arm/cpu.h 2008-04-01 17:19:11 UTC (rev 4156)
@@ -86,7 +86,8 @@
/* cpsr flag cache for faster execution */
uint32_t CF; /* 0 or 1 */
uint32_t VF; /* V is the bit 31. All other bits are undefined */
- uint32_t NZF; /* N is bit 31. Z is computed from NZF */
+ uint32_t NF; /* N is bit 31. All other bits are undefined. */
+ uint32_t ZF; /* Z set if zero. */
uint32_t QF; /* 0 or 1 */
uint32_t GE; /* cpsr[19:16] */
uint32_t thumb; /* cpsr[5]. 0 = arm mode, 1 = thumb mode. */
@@ -254,8 +255,8 @@
static inline uint32_t xpsr_read(CPUARMState *env)
{
int ZF;
- ZF = (env->NZF == 0);
- return (env->NZF & 0x80000000) | (ZF << 30)
+ ZF = (env->ZF == 0);
+ return (env->NF & 0x80000000) | (ZF << 30)
| (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
| (env->thumb << 24) | ((env->condexec_bits & 3) << 25)
| ((env->condexec_bits & 0xfc) << 8)
@@ -265,9 +266,9 @@
/* 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)
{
- /* NOTE: N = 1 and Z = 1 cannot be stored currently */
if (mask & CPSR_NZCV) {
- env->NZF = (val & 0xc0000000) ^ 0x40000000;
+ env->ZF = (~val) & CPSR_Z;
+ env->NF = val;
env->CF = (val >> 29) & 1;
env->VF = (val << 3) & 0x80000000;
}
Modified: trunk/target-arm/helper.c
===================================================================
--- trunk/target-arm/helper.c 2008-03-31 23:41:24 UTC (rev 4155)
+++ trunk/target-arm/helper.c 2008-04-01 17:19:11 UTC (rev 4156)
@@ -259,8 +259,8 @@
uint32_t cpsr_read(CPUARMState *env)
{
int ZF;
- ZF = (env->NZF == 0);
- return env->uncached_cpsr | (env->NZF & 0x80000000) | (ZF << 30) |
+ ZF = (env->ZF == 0);
+ return env->uncached_cpsr | (env->NF & 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)
@@ -269,9 +269,9 @@
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->ZF = (~val) & CPSR_Z;
+ env->NF = val;
env->CF = (val >> 29) & 1;
env->VF = (val << 3) & 0x80000000;
}
@@ -1690,10 +1690,8 @@
}
}
case 7: /* Cache control. */
- /* ??? This is for test, clean and invaidate operations that set the
- Z flag. We can't represent N = Z = 1, so it also clears
- the N flag. Oh well. */
- env->NZF = 0;
+ /* FIXME: Should only clear Z flag if destination is r15. */
+ env->ZF = 0;
return 0;
case 8: /* MMU TLB control. */
goto bad_reg;
Modified: trunk/target-arm/op_helper.c
===================================================================
--- trunk/target-arm/op_helper.c 2008-03-31 23:41:24 UTC (rev 4155)
+++ trunk/target-arm/op_helper.c 2008-04-01 17:19:11 UTC (rev 4156)
@@ -315,7 +315,7 @@
{
uint32_t result;
result = T0 + T1;
- env->NZF = result;
+ env->NF = env->ZF = result;
env->CF = result < a;
env->VF = (a ^ b ^ -1) & (a ^ result);
return result;
@@ -332,7 +332,7 @@
env->CF = result <= a;
}
env->VF = (a ^ b ^ -1) & (a ^ result);
- env->NZF = result;
+ env->NF = env->ZF = result;
return result;
}
@@ -340,7 +340,7 @@
{
uint32_t result;
result = a - b;
- env->NZF = result;
+ env->NF = env->ZF = result;
env->CF = a >= b;
env->VF = (a ^ b) & (a ^ result);
return result;
@@ -357,7 +357,7 @@
env->CF = a >= b;
}
env->VF = (a ^ b) & (a ^ result);
- env->NZF = result;
+ env->NF = env->ZF = result;
return result;
}
Modified: trunk/target-arm/translate.c
===================================================================
--- trunk/target-arm/translate.c 2008-03-31 23:41:24 UTC (rev 4155)
+++ trunk/target-arm/translate.c 2008-04-01 17:19:11 UTC (rev 4156)
@@ -423,7 +423,8 @@
/* Set N and Z flags from var. */
static inline void gen_logic_CC(TCGv var)
{
- tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NZF));
+ tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
+ tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
}
/* T0 += T1 + CF. */
@@ -679,11 +680,11 @@
zero = tcg_const_i32(0);
switch (cc) {
case 0: /* eq: Z */
- tmp = load_cpu_field(NZF);
+ tmp = load_cpu_field(ZF);
tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
break;
case 1: /* ne: !Z */
- tmp = load_cpu_field(NZF);
+ tmp = load_cpu_field(ZF);
tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label);
break;
case 2: /* cs: C */
@@ -695,11 +696,11 @@
tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
break;
case 4: /* mi: N */
- tmp = load_cpu_field(NZF);
+ tmp = load_cpu_field(NF);
tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
break;
case 5: /* pl: !N */
- tmp = load_cpu_field(NZF);
+ tmp = load_cpu_field(NF);
tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
break;
case 6: /* vs: V */
@@ -715,7 +716,7 @@
tmp = load_cpu_field(CF);
tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, inv);
dead_tmp(tmp);
- tmp = load_cpu_field(NZF);
+ tmp = load_cpu_field(ZF);
tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label);
gen_set_label(inv);
break;
@@ -723,41 +724,41 @@
tmp = load_cpu_field(CF);
tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
dead_tmp(tmp);
- tmp = load_cpu_field(NZF);
+ tmp = load_cpu_field(ZF);
tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
break;
case 10: /* ge: N == V -> N ^ V == 0 */
tmp = load_cpu_field(VF);
- tmp2 = load_cpu_field(NZF);
+ tmp2 = load_cpu_field(NF);
tcg_gen_xor_i32(tmp, tmp, tmp2);
dead_tmp(tmp2);
tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
break;
case 11: /* lt: N != V -> N ^ V != 0 */
tmp = load_cpu_field(VF);
- tmp2 = load_cpu_field(NZF);
+ tmp2 = load_cpu_field(NF);
tcg_gen_xor_i32(tmp, tmp, tmp2);
dead_tmp(tmp2);
tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
break;
case 12: /* gt: !Z && N == V */
inv = gen_new_label();
- tmp = load_cpu_field(NZF);
+ tmp = load_cpu_field(ZF);
tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, inv);
dead_tmp(tmp);
tmp = load_cpu_field(VF);
- tmp2 = load_cpu_field(NZF);
+ tmp2 = load_cpu_field(NF);
tcg_gen_xor_i32(tmp, tmp, tmp2);
dead_tmp(tmp2);
tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
gen_set_label(inv);
break;
case 13: /* le: Z || N != V */
- tmp = load_cpu_field(NZF);
+ tmp = load_cpu_field(ZF);
tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
dead_tmp(tmp);
tmp = load_cpu_field(VF);
- tmp2 = load_cpu_field(NZF);
+ tmp2 = load_cpu_field(NF);
tcg_gen_xor_i32(tmp, tmp, tmp2);
dead_tmp(tmp2);
tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
@@ -5641,7 +5642,8 @@
{
TCGv tmp = new_tmp();
gen_helper_logicq_cc(tmp, val);
- store_cpu_field(tmp, NZF);
+ gen_logic_CC(tmp);
+ dead_tmp(tmp);
}
static void disas_arm_insn(CPUState * env, DisasContext *s)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] [4156] ARM N=Z=1 flag fix.,
Paul Brook <=