From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Jgk8h-0008Iq-W0 for qemu-devel@nongnu.org; Tue, 01 Apr 2008 13:19:16 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Jgk8g-0008IB-KS for qemu-devel@nongnu.org; Tue, 01 Apr 2008 13:19:15 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Jgk8g-0008I8-Hh for qemu-devel@nongnu.org; Tue, 01 Apr 2008 13:19:14 -0400 Received: from savannah.gnu.org ([199.232.41.3] helo=sv.gnu.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1Jgk8g-00053y-7F for qemu-devel@nongnu.org; Tue, 01 Apr 2008 13:19:14 -0400 Received: from cvs.savannah.gnu.org ([199.232.41.69]) by sv.gnu.org with esmtp (Exim 4.63) (envelope-from ) id 1Jgk8f-0001G9-A5 for qemu-devel@nongnu.org; Tue, 01 Apr 2008 17:19:13 +0000 Received: from pbrook by cvs.savannah.gnu.org with local (Exim 4.63) (envelope-from ) id 1Jgk8e-0001FM-F4 for qemu-devel@nongnu.org; Tue, 01 Apr 2008 17:19:12 +0000 MIME-Version: 1.0 Errors-To: pbrook Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Paul Brook Message-Id: Date: Tue, 01 Apr 2008 17:19:12 +0000 Subject: [Qemu-devel] [4156] ARM N=Z=1 flag fix. Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org 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)