Revision 2623c1ec

b/target-mips/cpu.h
411 411
    int error_code;
412 412
    uint32_t hflags;    /* CPU State */
413 413
    /* TMASK defines different execution modes */
414
#define MIPS_HFLAG_TMASK  0x01FF
414
#define MIPS_HFLAG_TMASK  0x03FF
415 415
#define MIPS_HFLAG_MODE   0x0007 /* execution modes                    */
416 416
    /* The KSU flags must be the lowest bits in hflags. The flag order
417 417
       must be the same as defined for CP0 Status. This allows to use
......
430 430
       and RSQRT.D.  */
431 431
#define MIPS_HFLAG_COP1X  0x0080 /* COP1X instructions enabled         */
432 432
#define MIPS_HFLAG_RE     0x0100 /* Reversed endianness                */
433
#define MIPS_HFLAG_UX     0x0200 /* 64-bit user mode                   */
433 434
    /* If translation is interrupted between the branch instruction and
434 435
     * the delay slot, record what type of branch it is so that we can
435 436
     * resume translation properly.  It might be possible to reduce
436 437
     * this from three bits to two.  */
437
#define MIPS_HFLAG_BMASK  0x0e00
438
#define MIPS_HFLAG_B      0x0200 /* Unconditional branch               */
439
#define MIPS_HFLAG_BC     0x0400 /* Conditional branch                 */
440
#define MIPS_HFLAG_BL     0x0600 /* Likely branch                      */
441
#define MIPS_HFLAG_BR     0x0800 /* branch to register (can't link TB) */
438
#define MIPS_HFLAG_BMASK  0x1C00
439
#define MIPS_HFLAG_B      0x0400 /* Unconditional branch               */
440
#define MIPS_HFLAG_BC     0x0800 /* Conditional branch                 */
441
#define MIPS_HFLAG_BL     0x0C00 /* Likely branch                      */
442
#define MIPS_HFLAG_BR     0x1000 /* branch to register (can't link TB) */
442 443
    target_ulong btarget;        /* Jump / branch target               */
443 444
    int bcond;                   /* Branch condition (if needed)       */
444 445

  
b/target-mips/exec.h
66 66
static inline void compute_hflags(CPUState *env)
67 67
{
68 68
    env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
69
                     MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU);
69
                     MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU |
70
                     MIPS_HFLAG_UX);
70 71
    if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
71 72
        !(env->CP0_Status & (1 << CP0St_ERL)) &&
72 73
        !(env->hflags & MIPS_HFLAG_DM)) {
......
77 78
        (env->CP0_Status & (1 << CP0St_PX)) ||
78 79
        (env->CP0_Status & (1 << CP0St_UX)))
79 80
        env->hflags |= MIPS_HFLAG_64;
81
    if (env->CP0_Status & (1 << CP0St_UX))
82
        env->hflags |= MIPS_HFLAG_UX;
80 83
#endif
81 84
    if ((env->CP0_Status & (1 << CP0St_CU0)) ||
82 85
        !(env->hflags & MIPS_HFLAG_KSU))
b/target-mips/translate.c
902 902
    /* For compatibility with 32-bit code, data reference in user mode
903 903
       with Status_UX = 0 should be casted to 32-bit and sign extended.
904 904
       See the MIPS64 PRA manual, section 4.10. */
905
    if ((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) {
906
        int l1 = gen_new_label();
907
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
908

  
909
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
910
        tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX));
911
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 0, l1);
905
    if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
906
        !(ctx->hflags & MIPS_HFLAG_UX)) {
912 907
        tcg_gen_ext32s_i64(t0, t0);
913
        gen_set_label(l1);
914
        tcg_temp_free(r_tmp);
915 908
    }
916 909
#endif
917 910
}

Also available in: Unified diff