Revision 6fbe23d5

b/target-arm/cpu.h
86 86
    /* cpsr flag cache for faster execution */
87 87
    uint32_t CF; /* 0 or 1 */
88 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 91
    uint32_t QF; /* 0 or 1 */
91 92
    uint32_t GE; /* cpsr[19:16] */
92 93
    uint32_t thumb; /* cpsr[5]. 0 = arm mode, 1 = thumb mode. */
......
254 255
static inline uint32_t xpsr_read(CPUARMState *env)
255 256
{
256 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 260
        | (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
260 261
        | (env->thumb << 24) | ((env->condexec_bits & 3) << 25)
261 262
        | ((env->condexec_bits & 0xfc) << 8)
......
265 266
/* Set the xPSR.  Note that some bits of mask must be all-set or all-clear.  */
266 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 269
    if (mask & CPSR_NZCV) {
270
        env->NZF = (val & 0xc0000000) ^ 0x40000000;
270
        env->ZF = (~val) & CPSR_Z;
271
        env->NF = val;
271 272
        env->CF = (val >> 29) & 1;
272 273
        env->VF = (val << 3) & 0x80000000;
273 274
    }
b/target-arm/helper.c
259 259
uint32_t cpsr_read(CPUARMState *env)
260 260
{
261 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 264
        (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
265 265
        | (env->thumb << 5) | ((env->condexec_bits & 3) << 25)
266 266
        | ((env->condexec_bits & 0xfc) << 8)
......
269 269

  
270 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 272
    if (mask & CPSR_NZCV) {
274
        env->NZF = (val & 0xc0000000) ^ 0x40000000;
273
        env->ZF = (~val) & CPSR_Z;
274
        env->NF = val;
275 275
        env->CF = (val >> 29) & 1;
276 276
        env->VF = (val << 3) & 0x80000000;
277 277
    }
......
1690 1690
	    }
1691 1691
        }
1692 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 1695
        return 0;
1698 1696
    case 8: /* MMU TLB control.  */
1699 1697
        goto bad_reg;
b/target-arm/op_helper.c
315 315
{
316 316
    uint32_t result;
317 317
    result = T0 + T1;
318
    env->NZF = result;
318
    env->NF = env->ZF = result;
319 319
    env->CF = result < a;
320 320
    env->VF = (a ^ b ^ -1) & (a ^ result);
321 321
    return result;
......
332 332
        env->CF = result <= a;
333 333
    }
334 334
    env->VF = (a ^ b ^ -1) & (a ^ result);
335
    env->NZF = result;
335
    env->NF = env->ZF = result;
336 336
    return result;
337 337
}
338 338

  
......
340 340
{
341 341
    uint32_t result;
342 342
    result = a - b;
343
    env->NZF = result;
343
    env->NF = env->ZF = result;
344 344
    env->CF = a >= b;
345 345
    env->VF = (a ^ b) & (a ^ result);
346 346
    return result;
......
357 357
        env->CF = a >= b;
358 358
    }
359 359
    env->VF = (a ^ b) & (a ^ result);
360
    env->NZF = result;
360
    env->NF = env->ZF = result;
361 361
    return result;
362 362
}
363 363

  
b/target-arm/translate.c
423 423
/* Set N and Z flags from var.  */
424 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 430
/* T0 += T1 + CF.  */
......
679 680
    zero = tcg_const_i32(0);
680 681
    switch (cc) {
681 682
    case 0: /* eq: Z */
682
        tmp = load_cpu_field(NZF);
683
        tmp = load_cpu_field(ZF);
683 684
        tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
684 685
        break;
685 686
    case 1: /* ne: !Z */
686
        tmp = load_cpu_field(NZF);
687
        tmp = load_cpu_field(ZF);
687 688
        tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label);
688 689
        break;
689 690
    case 2: /* cs: C */
......
695 696
        tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
696 697
        break;
697 698
    case 4: /* mi: N */
698
        tmp = load_cpu_field(NZF);
699
        tmp = load_cpu_field(NF);
699 700
        tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
700 701
        break;
701 702
    case 5: /* pl: !N */
702
        tmp = load_cpu_field(NZF);
703
        tmp = load_cpu_field(NF);
703 704
        tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
704 705
        break;
705 706
    case 6: /* vs: V */
......
715 716
        tmp = load_cpu_field(CF);
716 717
        tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, inv);
717 718
        dead_tmp(tmp);
718
        tmp = load_cpu_field(NZF);
719
        tmp = load_cpu_field(ZF);
719 720
        tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label);
720 721
        gen_set_label(inv);
721 722
        break;
......
723 724
        tmp = load_cpu_field(CF);
724 725
        tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
725 726
        dead_tmp(tmp);
726
        tmp = load_cpu_field(NZF);
727
        tmp = load_cpu_field(ZF);
727 728
        tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
728 729
        break;
729 730
    case 10: /* ge: N == V -> N ^ V == 0 */
730 731
        tmp = load_cpu_field(VF);
731
        tmp2 = load_cpu_field(NZF);
732
        tmp2 = load_cpu_field(NF);
732 733
        tcg_gen_xor_i32(tmp, tmp, tmp2);
733 734
        dead_tmp(tmp2);
734 735
        tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
735 736
        break;
736 737
    case 11: /* lt: N != V -> N ^ V != 0 */
737 738
        tmp = load_cpu_field(VF);
738
        tmp2 = load_cpu_field(NZF);
739
        tmp2 = load_cpu_field(NF);
739 740
        tcg_gen_xor_i32(tmp, tmp, tmp2);
740 741
        dead_tmp(tmp2);
741 742
        tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
742 743
        break;
743 744
    case 12: /* gt: !Z && N == V */
744 745
        inv = gen_new_label();
745
        tmp = load_cpu_field(NZF);
746
        tmp = load_cpu_field(ZF);
746 747
        tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, inv);
747 748
        dead_tmp(tmp);
748 749
        tmp = load_cpu_field(VF);
749
        tmp2 = load_cpu_field(NZF);
750
        tmp2 = load_cpu_field(NF);
750 751
        tcg_gen_xor_i32(tmp, tmp, tmp2);
751 752
        dead_tmp(tmp2);
752 753
        tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
753 754
        gen_set_label(inv);
754 755
        break;
755 756
    case 13: /* le: Z || N != V */
756
        tmp = load_cpu_field(NZF);
757
        tmp = load_cpu_field(ZF);
757 758
        tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
758 759
        dead_tmp(tmp);
759 760
        tmp = load_cpu_field(VF);
760
        tmp2 = load_cpu_field(NZF);
761
        tmp2 = load_cpu_field(NF);
761 762
        tcg_gen_xor_i32(tmp, tmp, tmp2);
762 763
        dead_tmp(tmp2);
763 764
        tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
......
5641 5642
{
5642 5643
    TCGv tmp = new_tmp();
5643 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 5649
static void disas_arm_insn(CPUState * env, DisasContext *s)

Also available in: Unified diff