Commit 6fbe23d50ed24044ac2d12281b0e7d580a2374d9

Authored by pbrook
1 parent f5d28393

ARM N=Z=1 flag fix.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4156 c046a42c-6fe2-441c-8c8c-71466251a162
target-arm/cpu.h
@@ -86,7 +86,8 @@ typedef struct CPUARMState { @@ -86,7 +86,8 @@ typedef struct CPUARMState {
86 /* cpsr flag cache for faster execution */ 86 /* cpsr flag cache for faster execution */
87 uint32_t CF; /* 0 or 1 */ 87 uint32_t CF; /* 0 or 1 */
88 uint32_t VF; /* V is the bit 31. All other bits are undefined */ 88 uint32_t VF; /* V is the bit 31. All other bits are undefined */
89 - uint32_t NZF; /* N is bit 31. Z is computed from NZF */ 89 + uint32_t NF; /* N is bit 31. All other bits are undefined. */
  90 + uint32_t ZF; /* Z set if zero. */
90 uint32_t QF; /* 0 or 1 */ 91 uint32_t QF; /* 0 or 1 */
91 uint32_t GE; /* cpsr[19:16] */ 92 uint32_t GE; /* cpsr[19:16] */
92 uint32_t thumb; /* cpsr[5]. 0 = arm mode, 1 = thumb mode. */ 93 uint32_t thumb; /* cpsr[5]. 0 = arm mode, 1 = thumb mode. */
@@ -254,8 +255,8 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask); @@ -254,8 +255,8 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask);
254 static inline uint32_t xpsr_read(CPUARMState *env) 255 static inline uint32_t xpsr_read(CPUARMState *env)
255 { 256 {
256 int ZF; 257 int ZF;
257 - ZF = (env->NZF == 0);  
258 - return (env->NZF & 0x80000000) | (ZF << 30) 258 + ZF = (env->ZF == 0);
  259 + return (env->NF & 0x80000000) | (ZF << 30)
259 | (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27) 260 | (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
260 | (env->thumb << 24) | ((env->condexec_bits & 3) << 25) 261 | (env->thumb << 24) | ((env->condexec_bits & 3) << 25)
261 | ((env->condexec_bits & 0xfc) << 8) 262 | ((env->condexec_bits & 0xfc) << 8)
@@ -265,9 +266,9 @@ static inline uint32_t xpsr_read(CPUARMState *env) @@ -265,9 +266,9 @@ static inline uint32_t xpsr_read(CPUARMState *env)
265 /* Set the xPSR. Note that some bits of mask must be all-set or all-clear. */ 266 /* Set the xPSR. Note that some bits of mask must be all-set or all-clear. */
266 static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) 267 static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
267 { 268 {
268 - /* NOTE: N = 1 and Z = 1 cannot be stored currently */  
269 if (mask & CPSR_NZCV) { 269 if (mask & CPSR_NZCV) {
270 - env->NZF = (val & 0xc0000000) ^ 0x40000000; 270 + env->ZF = (~val) & CPSR_Z;
  271 + env->NF = val;
271 env->CF = (val >> 29) & 1; 272 env->CF = (val >> 29) & 1;
272 env->VF = (val << 3) & 0x80000000; 273 env->VF = (val << 3) & 0x80000000;
273 } 274 }
target-arm/helper.c
@@ -259,8 +259,8 @@ void cpu_arm_close(CPUARMState *env) @@ -259,8 +259,8 @@ void cpu_arm_close(CPUARMState *env)
259 uint32_t cpsr_read(CPUARMState *env) 259 uint32_t cpsr_read(CPUARMState *env)
260 { 260 {
261 int ZF; 261 int ZF;
262 - ZF = (env->NZF == 0);  
263 - return env->uncached_cpsr | (env->NZF & 0x80000000) | (ZF << 30) | 262 + ZF = (env->ZF == 0);
  263 + return env->uncached_cpsr | (env->NF & 0x80000000) | (ZF << 30) |
264 (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27) 264 (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
265 | (env->thumb << 5) | ((env->condexec_bits & 3) << 25) 265 | (env->thumb << 5) | ((env->condexec_bits & 3) << 25)
266 | ((env->condexec_bits & 0xfc) << 8) 266 | ((env->condexec_bits & 0xfc) << 8)
@@ -269,9 +269,9 @@ uint32_t cpsr_read(CPUARMState *env) @@ -269,9 +269,9 @@ uint32_t cpsr_read(CPUARMState *env)
269 269
270 void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) 270 void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
271 { 271 {
272 - /* NOTE: N = 1 and Z = 1 cannot be stored currently */  
273 if (mask & CPSR_NZCV) { 272 if (mask & CPSR_NZCV) {
274 - env->NZF = (val & 0xc0000000) ^ 0x40000000; 273 + env->ZF = (~val) & CPSR_Z;
  274 + env->NF = val;
275 env->CF = (val >> 29) & 1; 275 env->CF = (val >> 29) & 1;
276 env->VF = (val << 3) & 0x80000000; 276 env->VF = (val << 3) & 0x80000000;
277 } 277 }
@@ -1690,10 +1690,8 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn) @@ -1690,10 +1690,8 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
1690 } 1690 }
1691 } 1691 }
1692 case 7: /* Cache control. */ 1692 case 7: /* Cache control. */
1693 - /* ??? This is for test, clean and invaidate operations that set the  
1694 - Z flag. We can't represent N = Z = 1, so it also clears  
1695 - the N flag. Oh well. */  
1696 - env->NZF = 0; 1693 + /* FIXME: Should only clear Z flag if destination is r15. */
  1694 + env->ZF = 0;
1697 return 0; 1695 return 0;
1698 case 8: /* MMU TLB control. */ 1696 case 8: /* MMU TLB control. */
1699 goto bad_reg; 1697 goto bad_reg;
target-arm/op_helper.c
@@ -315,7 +315,7 @@ uint32_t HELPER (add_cc)(uint32_t a, uint32_t b) @@ -315,7 +315,7 @@ uint32_t HELPER (add_cc)(uint32_t a, uint32_t b)
315 { 315 {
316 uint32_t result; 316 uint32_t result;
317 result = T0 + T1; 317 result = T0 + T1;
318 - env->NZF = result; 318 + env->NF = env->ZF = result;
319 env->CF = result < a; 319 env->CF = result < a;
320 env->VF = (a ^ b ^ -1) & (a ^ result); 320 env->VF = (a ^ b ^ -1) & (a ^ result);
321 return result; 321 return result;
@@ -332,7 +332,7 @@ uint32_t HELPER(adc_cc)(uint32_t a, uint32_t b) @@ -332,7 +332,7 @@ uint32_t HELPER(adc_cc)(uint32_t a, uint32_t b)
332 env->CF = result <= a; 332 env->CF = result <= a;
333 } 333 }
334 env->VF = (a ^ b ^ -1) & (a ^ result); 334 env->VF = (a ^ b ^ -1) & (a ^ result);
335 - env->NZF = result; 335 + env->NF = env->ZF = result;
336 return result; 336 return result;
337 } 337 }
338 338
@@ -340,7 +340,7 @@ uint32_t HELPER(sub_cc)(uint32_t a, uint32_t b) @@ -340,7 +340,7 @@ uint32_t HELPER(sub_cc)(uint32_t a, uint32_t b)
340 { 340 {
341 uint32_t result; 341 uint32_t result;
342 result = a - b; 342 result = a - b;
343 - env->NZF = result; 343 + env->NF = env->ZF = result;
344 env->CF = a >= b; 344 env->CF = a >= b;
345 env->VF = (a ^ b) & (a ^ result); 345 env->VF = (a ^ b) & (a ^ result);
346 return result; 346 return result;
@@ -357,7 +357,7 @@ uint32_t HELPER(sbc_cc)(uint32_t a, uint32_t b) @@ -357,7 +357,7 @@ uint32_t HELPER(sbc_cc)(uint32_t a, uint32_t b)
357 env->CF = a >= b; 357 env->CF = a >= b;
358 } 358 }
359 env->VF = (a ^ b) & (a ^ result); 359 env->VF = (a ^ b) & (a ^ result);
360 - env->NZF = result; 360 + env->NF = env->ZF = result;
361 return result; 361 return result;
362 } 362 }
363 363
target-arm/translate.c
@@ -423,7 +423,8 @@ static void gen_set_CF_bit31(TCGv var) @@ -423,7 +423,8 @@ static void gen_set_CF_bit31(TCGv var)
423 /* Set N and Z flags from var. */ 423 /* Set N and Z flags from var. */
424 static inline void gen_logic_CC(TCGv var) 424 static inline void gen_logic_CC(TCGv var)
425 { 425 {
426 - tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NZF)); 426 + tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
  427 + tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
427 } 428 }
428 429
429 /* T0 += T1 + CF. */ 430 /* T0 += T1 + CF. */
@@ -679,11 +680,11 @@ static void gen_test_cc(int cc, int label) @@ -679,11 +680,11 @@ static void gen_test_cc(int cc, int label)
679 zero = tcg_const_i32(0); 680 zero = tcg_const_i32(0);
680 switch (cc) { 681 switch (cc) {
681 case 0: /* eq: Z */ 682 case 0: /* eq: Z */
682 - tmp = load_cpu_field(NZF); 683 + tmp = load_cpu_field(ZF);
683 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label); 684 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
684 break; 685 break;
685 case 1: /* ne: !Z */ 686 case 1: /* ne: !Z */
686 - tmp = load_cpu_field(NZF); 687 + tmp = load_cpu_field(ZF);
687 tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label); 688 tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label);
688 break; 689 break;
689 case 2: /* cs: C */ 690 case 2: /* cs: C */
@@ -695,11 +696,11 @@ static void gen_test_cc(int cc, int label) @@ -695,11 +696,11 @@ static void gen_test_cc(int cc, int label)
695 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label); 696 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
696 break; 697 break;
697 case 4: /* mi: N */ 698 case 4: /* mi: N */
698 - tmp = load_cpu_field(NZF); 699 + tmp = load_cpu_field(NF);
699 tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label); 700 tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
700 break; 701 break;
701 case 5: /* pl: !N */ 702 case 5: /* pl: !N */
702 - tmp = load_cpu_field(NZF); 703 + tmp = load_cpu_field(NF);
703 tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label); 704 tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
704 break; 705 break;
705 case 6: /* vs: V */ 706 case 6: /* vs: V */
@@ -715,7 +716,7 @@ static void gen_test_cc(int cc, int label) @@ -715,7 +716,7 @@ static void gen_test_cc(int cc, int label)
715 tmp = load_cpu_field(CF); 716 tmp = load_cpu_field(CF);
716 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, inv); 717 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, inv);
717 dead_tmp(tmp); 718 dead_tmp(tmp);
718 - tmp = load_cpu_field(NZF); 719 + tmp = load_cpu_field(ZF);
719 tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label); 720 tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label);
720 gen_set_label(inv); 721 gen_set_label(inv);
721 break; 722 break;
@@ -723,41 +724,41 @@ static void gen_test_cc(int cc, int label) @@ -723,41 +724,41 @@ static void gen_test_cc(int cc, int label)
723 tmp = load_cpu_field(CF); 724 tmp = load_cpu_field(CF);
724 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label); 725 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
725 dead_tmp(tmp); 726 dead_tmp(tmp);
726 - tmp = load_cpu_field(NZF); 727 + tmp = load_cpu_field(ZF);
727 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label); 728 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
728 break; 729 break;
729 case 10: /* ge: N == V -> N ^ V == 0 */ 730 case 10: /* ge: N == V -> N ^ V == 0 */
730 tmp = load_cpu_field(VF); 731 tmp = load_cpu_field(VF);
731 - tmp2 = load_cpu_field(NZF); 732 + tmp2 = load_cpu_field(NF);
732 tcg_gen_xor_i32(tmp, tmp, tmp2); 733 tcg_gen_xor_i32(tmp, tmp, tmp2);
733 dead_tmp(tmp2); 734 dead_tmp(tmp2);
734 tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label); 735 tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
735 break; 736 break;
736 case 11: /* lt: N != V -> N ^ V != 0 */ 737 case 11: /* lt: N != V -> N ^ V != 0 */
737 tmp = load_cpu_field(VF); 738 tmp = load_cpu_field(VF);
738 - tmp2 = load_cpu_field(NZF); 739 + tmp2 = load_cpu_field(NF);
739 tcg_gen_xor_i32(tmp, tmp, tmp2); 740 tcg_gen_xor_i32(tmp, tmp, tmp2);
740 dead_tmp(tmp2); 741 dead_tmp(tmp2);
741 tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label); 742 tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
742 break; 743 break;
743 case 12: /* gt: !Z && N == V */ 744 case 12: /* gt: !Z && N == V */
744 inv = gen_new_label(); 745 inv = gen_new_label();
745 - tmp = load_cpu_field(NZF); 746 + tmp = load_cpu_field(ZF);
746 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, inv); 747 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, inv);
747 dead_tmp(tmp); 748 dead_tmp(tmp);
748 tmp = load_cpu_field(VF); 749 tmp = load_cpu_field(VF);
749 - tmp2 = load_cpu_field(NZF); 750 + tmp2 = load_cpu_field(NF);
750 tcg_gen_xor_i32(tmp, tmp, tmp2); 751 tcg_gen_xor_i32(tmp, tmp, tmp2);
751 dead_tmp(tmp2); 752 dead_tmp(tmp2);
752 tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label); 753 tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
753 gen_set_label(inv); 754 gen_set_label(inv);
754 break; 755 break;
755 case 13: /* le: Z || N != V */ 756 case 13: /* le: Z || N != V */
756 - tmp = load_cpu_field(NZF); 757 + tmp = load_cpu_field(ZF);
757 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label); 758 tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
758 dead_tmp(tmp); 759 dead_tmp(tmp);
759 tmp = load_cpu_field(VF); 760 tmp = load_cpu_field(VF);
760 - tmp2 = load_cpu_field(NZF); 761 + tmp2 = load_cpu_field(NF);
761 tcg_gen_xor_i32(tmp, tmp, tmp2); 762 tcg_gen_xor_i32(tmp, tmp, tmp2);
762 dead_tmp(tmp2); 763 dead_tmp(tmp2);
763 tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label); 764 tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
@@ -5641,7 +5642,8 @@ static void gen_logicq_cc(TCGv val) @@ -5641,7 +5642,8 @@ static void gen_logicq_cc(TCGv val)
5641 { 5642 {
5642 TCGv tmp = new_tmp(); 5643 TCGv tmp = new_tmp();
5643 gen_helper_logicq_cc(tmp, val); 5644 gen_helper_logicq_cc(tmp, val);
5644 - store_cpu_field(tmp, NZF); 5645 + gen_logic_CC(tmp);
  5646 + dead_tmp(tmp);
5645 } 5647 }
5646 5648
5647 static void disas_arm_insn(CPUState * env, DisasContext *s) 5649 static void disas_arm_insn(CPUState * env, DisasContext *s)