Revision ead9360e

b/cpu-exec.c
194 194
#elif defined(TARGET_MIPS)
195 195
    flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
196 196
    cs_base = 0;
197
    pc = env->PC;
197
    pc = env->PC[env->current_tc];
198 198
#elif defined(TARGET_M68K)
199 199
    flags = (env->fpcr & M68K_FPCR_PREC)  /* Bit  6 */
200 200
            | (env->sr & SR_S)            /* Bit  13 */
b/gdbstub.c
559 559
    ptr = mem_buf;
560 560
    for (i = 0; i < 32; i++)
561 561
      {
562
        *(target_ulong *)ptr = tswapl(env->gpr[i]);
562
        *(target_ulong *)ptr = tswapl(env->gpr[i][env->current_tc]);
563 563
        ptr += sizeof(target_ulong);
564 564
      }
565 565

  
566 566
    *(target_ulong *)ptr = tswapl(env->CP0_Status);
567 567
    ptr += sizeof(target_ulong);
568 568

  
569
    *(target_ulong *)ptr = tswapl(env->LO);
569
    *(target_ulong *)ptr = tswapl(env->LO[0][env->current_tc]);
570 570
    ptr += sizeof(target_ulong);
571 571

  
572
    *(target_ulong *)ptr = tswapl(env->HI);
572
    *(target_ulong *)ptr = tswapl(env->HI[0][env->current_tc]);
573 573
    ptr += sizeof(target_ulong);
574 574

  
575 575
    *(target_ulong *)ptr = tswapl(env->CP0_BadVAddr);
......
578 578
    *(target_ulong *)ptr = tswapl(env->CP0_Cause);
579 579
    ptr += sizeof(target_ulong);
580 580

  
581
    *(target_ulong *)ptr = tswapl(env->PC);
581
    *(target_ulong *)ptr = tswapl(env->PC[env->current_tc]);
582 582
    ptr += sizeof(target_ulong);
583 583

  
584 584
    if (env->CP0_Config1 & (1 << CP0C1_FP))
585 585
      {
586 586
        for (i = 0; i < 32; i++)
587 587
          {
588
            *(target_ulong *)ptr = tswapl(env->fpr[i].fs[FP_ENDIAN_IDX]);
588
            *(target_ulong *)ptr = tswapl(env->fpu->fpr[i].fs[FP_ENDIAN_IDX]);
589 589
            ptr += sizeof(target_ulong);
590 590
          }
591 591

  
592
        *(target_ulong *)ptr = tswapl(env->fcr31);
592
        *(target_ulong *)ptr = tswapl(env->fpu->fcr31);
593 593
        ptr += sizeof(target_ulong);
594 594

  
595
        *(target_ulong *)ptr = tswapl(env->fcr0);
595
        *(target_ulong *)ptr = tswapl(env->fpu->fcr0);
596 596
        ptr += sizeof(target_ulong);
597 597
      }
598 598

  
......
611 611
    float_round_down
612 612
  };
613 613
#define RESTORE_ROUNDING_MODE \
614
    set_float_rounding_mode(ieee_rm[env->fcr31 & 3], &env->fp_status)
614
    set_float_rounding_mode(ieee_rm[env->fpu->fcr31 & 3], &env->fpu->fp_status)
615 615

  
616 616
static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
617 617
{
......
621 621
    ptr = mem_buf;
622 622
    for (i = 0; i < 32; i++)
623 623
      {
624
        env->gpr[i] = tswapl(*(target_ulong *)ptr);
624
        env->gpr[i][env->current_tc] = tswapl(*(target_ulong *)ptr);
625 625
        ptr += sizeof(target_ulong);
626 626
      }
627 627

  
628 628
    env->CP0_Status = tswapl(*(target_ulong *)ptr);
629 629
    ptr += sizeof(target_ulong);
630 630

  
631
    env->LO = tswapl(*(target_ulong *)ptr);
631
    env->LO[0][env->current_tc] = tswapl(*(target_ulong *)ptr);
632 632
    ptr += sizeof(target_ulong);
633 633

  
634
    env->HI = tswapl(*(target_ulong *)ptr);
634
    env->HI[0][env->current_tc] = tswapl(*(target_ulong *)ptr);
635 635
    ptr += sizeof(target_ulong);
636 636

  
637 637
    env->CP0_BadVAddr = tswapl(*(target_ulong *)ptr);
......
640 640
    env->CP0_Cause = tswapl(*(target_ulong *)ptr);
641 641
    ptr += sizeof(target_ulong);
642 642

  
643
    env->PC = tswapl(*(target_ulong *)ptr);
643
    env->PC[env->current_tc] = tswapl(*(target_ulong *)ptr);
644 644
    ptr += sizeof(target_ulong);
645 645

  
646 646
    if (env->CP0_Config1 & (1 << CP0C1_FP))
647 647
      {
648 648
        for (i = 0; i < 32; i++)
649 649
          {
650
            env->fpr[i].fs[FP_ENDIAN_IDX] = tswapl(*(target_ulong *)ptr);
650
            env->fpu->fpr[i].fs[FP_ENDIAN_IDX] = tswapl(*(target_ulong *)ptr);
651 651
            ptr += sizeof(target_ulong);
652 652
          }
653 653

  
654
        env->fcr31 = tswapl(*(target_ulong *)ptr) & 0x0183FFFF;
654
        env->fpu->fcr31 = tswapl(*(target_ulong *)ptr) & 0x0183FFFF;
655 655
        ptr += sizeof(target_ulong);
656 656

  
657
        env->fcr0 = tswapl(*(target_ulong *)ptr);
657
        env->fpu->fcr0 = tswapl(*(target_ulong *)ptr);
658 658
        ptr += sizeof(target_ulong);
659 659

  
660 660
        /* set rounding mode */
......
775 775
#elif defined (TARGET_SH4)
776 776
            env->pc = addr;
777 777
#elif defined (TARGET_MIPS)
778
            env->PC = addr;
778
            env->PC[env->current_tc] = addr;
779 779
#endif
780 780
        }
781 781
#ifdef CONFIG_USER_ONLY
......
799 799
#elif defined (TARGET_SH4)
800 800
            env->pc = addr;
801 801
#elif defined (TARGET_MIPS)
802
            env->PC = addr;
802
            env->PC[env->current_tc] = addr;
803 803
#endif
804 804
        }
805 805
        cpu_single_step(env, 1);
b/hw/mips_r4k.c
77 77
    if (kernel_size >= 0) {
78 78
        if ((entry & ~0x7fffffffULL) == 0x80000000)
79 79
            entry = (int32_t)entry;
80
        env->PC = entry;
80
        env->PC[env->current_tc] = entry;
81 81
    } else {
82 82
        fprintf(stderr, "qemu: could not load kernel '%s'\n",
83 83
                kernel_filename);
b/hw/mips_timer.c
10 10
    static uint32_t seed = 0;
11 11
    uint32_t idx;
12 12
    seed = seed * 314159 + 1;
13
    idx = (seed >> 16) % (env->nb_tlb - env->CP0_Wired) + env->CP0_Wired;
13
    idx = (seed >> 16) % (env->tlb->nb_tlb - env->CP0_Wired) + env->CP0_Wired;
14 14
    return idx;
15 15
}
16 16

  
b/linux-user/main.c
1374 1374
        trapnr = cpu_mips_exec(env);
1375 1375
        switch(trapnr) {
1376 1376
        case EXCP_SYSCALL:
1377
            syscall_num = env->gpr[2] - 4000;
1378
            env->PC += 4;
1377
            syscall_num = env->gpr[2][env->current_tc] - 4000;
1378
            env->PC[env->current_tc] += 4;
1379 1379
            if (syscall_num >= sizeof(mips_syscall_args)) {
1380 1380
                ret = -ENOSYS;
1381 1381
            } else {
......
1384 1384
                target_ulong arg5 = 0, arg6 = 0, arg7 = 0, arg8 = 0;
1385 1385

  
1386 1386
                nb_args = mips_syscall_args[syscall_num];
1387
                sp_reg = env->gpr[29];
1387
                sp_reg = env->gpr[29][env->current_tc];
1388 1388
                switch (nb_args) {
1389 1389
                /* these arguments are taken from the stack */
1390 1390
                case 8: arg8 = tgetl(sp_reg + 28);
......
1394 1394
                default:
1395 1395
                    break;
1396 1396
                }
1397
                ret = do_syscall(env, env->gpr[2],
1398
                                 env->gpr[4], env->gpr[5],
1399
                                 env->gpr[6], env->gpr[7],
1397
                ret = do_syscall(env, env->gpr[2][env->current_tc],
1398
                                 env->gpr[4][env->current_tc],
1399
                                 env->gpr[5][env->current_tc],
1400
                                 env->gpr[6][env->current_tc],
1401
                                 env->gpr[7][env->current_tc],
1400 1402
                                 arg5, arg6/*, arg7, arg8*/);
1401 1403
            }
1402 1404
            if ((unsigned int)ret >= (unsigned int)(-1133)) {
1403
                env->gpr[7] = 1; /* error flag */
1405
                env->gpr[7][env->current_tc] = 1; /* error flag */
1404 1406
                ret = -ret;
1405 1407
            } else {
1406
                env->gpr[7] = 0; /* error flag */
1408
                env->gpr[7][env->current_tc] = 0; /* error flag */
1407 1409
            }
1408
            env->gpr[2] = ret;
1410
            env->gpr[2][env->current_tc] = ret;
1409 1411
            break;
1410 1412
        case EXCP_TLBL:
1411 1413
        case EXCP_TLBS:
......
2053 2055
        cpu_mips_register(env, def);
2054 2056

  
2055 2057
        for(i = 0; i < 32; i++) {
2056
            env->gpr[i] = regs->regs[i];
2058
            env->gpr[i][env->current_tc] = regs->regs[i];
2057 2059
        }
2058
        env->PC = regs->cp0_epc;
2060
        env->PC[env->current_tc] = regs->cp0_epc;
2059 2061
    }
2060 2062
#elif defined(TARGET_SH4)
2061 2063
    {
b/linux-user/signal.c
1686 1686
{
1687 1687
    int err = 0;
1688 1688

  
1689
    err |= __put_user(regs->PC, &sc->sc_pc);
1689
    err |= __put_user(regs->PC[regs->current_tc], &sc->sc_pc);
1690 1690

  
1691
#define save_gp_reg(i) do {   					\
1692
        err |= __put_user(regs->gpr[i], &sc->sc_regs[i]);	\
1691
#define save_gp_reg(i) do {   							\
1692
        err |= __put_user(regs->gpr[i][regs->current_tc], &sc->sc_regs[i]);	\
1693 1693
    } while(0)
1694 1694
    __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
1695 1695
    save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
......
1702 1702
    save_gp_reg(31);
1703 1703
#undef save_gp_reg
1704 1704

  
1705
    err |= __put_user(regs->HI, &sc->sc_mdhi);
1706
    err |= __put_user(regs->LO, &sc->sc_mdlo);
1705
    err |= __put_user(regs->HI[0][regs->current_tc], &sc->sc_mdhi);
1706
    err |= __put_user(regs->LO[0][regs->current_tc], &sc->sc_mdlo);
1707 1707

  
1708 1708
    /* Not used yet, but might be useful if we ever have DSP suppport */
1709 1709
#if 0
......
1763 1763

  
1764 1764
    err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
1765 1765

  
1766
    err |= __get_user(regs->HI, &sc->sc_mdhi);
1767
    err |= __get_user(regs->LO, &sc->sc_mdlo);
1766
    err |= __get_user(regs->HI[0][regs->current_tc], &sc->sc_mdhi);
1767
    err |= __get_user(regs->LO[0][regs->current_tc], &sc->sc_mdlo);
1768 1768

  
1769
#define restore_gp_reg(i) do {   					\
1770
        err |= __get_user(regs->gpr[i], &sc->sc_regs[i]);		\
1769
#define restore_gp_reg(i) do {   							\
1770
        err |= __get_user(regs->gpr[i][regs->current_tc], &sc->sc_regs[i]);		\
1771 1771
    } while(0)
1772 1772
    restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
1773 1773
    restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
......
1833 1833
    unsigned long sp;
1834 1834

  
1835 1835
    /* Default to using normal stack */
1836
    sp = regs->gpr[29];
1836
    sp = regs->gpr[29][regs->current_tc];
1837 1837

  
1838 1838
    /*
1839 1839
     * FPU emulator may have it's own trampoline active just
......
1881 1881
    * $25 and PC point to the signal handler, $29 points to the
1882 1882
    * struct sigframe.
1883 1883
    */
1884
    regs->gpr[ 4] = sig;
1885
    regs->gpr[ 5] = 0;
1886
    regs->gpr[ 6] = h2g(&frame->sf_sc);
1887
    regs->gpr[29] = h2g(frame);
1888
    regs->gpr[31] = h2g(frame->sf_code);
1884
    regs->gpr[ 4][regs->current_tc] = sig;
1885
    regs->gpr[ 5][regs->current_tc] = 0;
1886
    regs->gpr[ 6][regs->current_tc] = h2g(&frame->sf_sc);
1887
    regs->gpr[29][regs->current_tc] = h2g(frame);
1888
    regs->gpr[31][regs->current_tc] = h2g(frame->sf_code);
1889 1889
    /* The original kernel code sets CP0_EPC to the handler
1890 1890
    * since it returns to userland using eret
1891 1891
    * we cannot do this here, and we must set PC directly */
1892
    regs->PC = regs->gpr[25] = ka->sa._sa_handler;
1892
    regs->PC[regs->current_tc] = regs->gpr[25][regs->current_tc] = ka->sa._sa_handler;
1893 1893
    return;
1894 1894

  
1895 1895
give_sigsegv:
......
1907 1907
#if defined(DEBUG_SIGNAL)
1908 1908
    fprintf(stderr, "do_sigreturn\n");
1909 1909
#endif
1910
    frame = (struct sigframe *) regs->gpr[29];
1910
    frame = (struct sigframe *) regs->gpr[29][regs->current_tc];
1911 1911
    if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
1912 1912
   	goto badframe;
1913 1913

  
......
1934 1934
    /* Unreached */
1935 1935
#endif
1936 1936
    
1937
    regs->PC = regs->CP0_EPC;
1937
    regs->PC[regs->current_tc] = regs->CP0_EPC;
1938 1938
    /* I am not sure this is right, but it seems to work
1939 1939
    * maybe a problem with nested signals ? */
1940 1940
    regs->CP0_EPC = 0;
b/linux-user/syscall.c
2189 2189
        /* ??? is this sufficient?  */
2190 2190
#elif defined(TARGET_MIPS)
2191 2191
        if (!newsp)
2192
            newsp = env->gpr[29];
2193
        new_env->gpr[29] = newsp;
2192
            newsp = env->gpr[29][env->current_tc];
2193
        new_env->gpr[29][env->current_tc] = newsp;
2194 2194
#elif defined(TARGET_PPC)
2195 2195
        if (!newsp)
2196 2196
            newsp = env->gpr[1];
......
2777 2777
            ret = get_errno(pipe(host_pipe));
2778 2778
            if (!is_error(ret)) {
2779 2779
#if defined(TARGET_MIPS)
2780
		((CPUMIPSState*)cpu_env)->gpr[3] = host_pipe[1];
2780
                CPUMIPSState *env = (CPUMIPSState*)cpu_env;
2781
		env->gpr[3][env->current_tc] = host_pipe[1];
2781 2782
		ret = host_pipe[0];
2782 2783
#else
2783 2784
                tput32(arg1, host_pipe[0]);
b/monitor.c
309 309
        term_printf(" pc=0x" TARGET_FMT_lx " npc=0x" TARGET_FMT_lx, env->pc, env->npc);
310 310
        if (env->halted)
311 311
            term_printf(" (halted)");
312
#elif defined(TARGET_MIPS)
313
        term_printf(" PC=0x" TARGET_FMT_lx, env->PC[env->current_tc]);
314
        if (env->halted)
315
            term_printf(" (halted)");
312 316
#endif
313 317
        term_printf("\n");
314 318
    }
b/target-mips/cpu.h
17 17
typedef unsigned int            uint_fast16_t;
18 18
#endif
19 19

  
20
typedef union fpr_t fpr_t;
21
union fpr_t {
22
    float64  fd;   /* ieee double precision */
23
    float32  fs[2];/* ieee single precision */
24
    uint64_t d;    /* binary double fixed-point */
25
    uint32_t w[2]; /* binary single fixed-point */
26
};
27
/* define FP_ENDIAN_IDX to access the same location
28
 * in the fpr_t union regardless of the host endianess
29
 */
30
#if defined(WORDS_BIGENDIAN)
31
#  define FP_ENDIAN_IDX 1
32
#else
33
#  define FP_ENDIAN_IDX 0
34
#endif
20
struct CPUMIPSState;
35 21

  
36 22
typedef struct r4k_tlb_t r4k_tlb_t;
37 23
struct r4k_tlb_t {
......
48 34
    target_ulong PFN[2];
49 35
};
50 36

  
51
typedef struct mips_def_t mips_def_t;
37
typedef struct CPUMIPSTLBContext CPUMIPSTLBContext;
38
struct CPUMIPSTLBContext {
39
    uint32_t nb_tlb;
40
    uint32_t tlb_in_use;
41
    int (*map_address) (struct CPUMIPSState *env, target_ulong *physical, int *prot, target_ulong address, int rw, int access_type);
42
    void (*do_tlbwi) (void);
43
    void (*do_tlbwr) (void);
44
    void (*do_tlbp) (void);
45
    void (*do_tlbr) (void);
46
    union {
47
        struct {
48
            r4k_tlb_t tlb[MIPS_TLB_MAX];
49
        } r4k;
50
    } mmu;
51
};
52 52

  
53
typedef struct CPUMIPSState CPUMIPSState;
54
struct CPUMIPSState {
55
    /* General integer registers */
56
    target_ulong gpr[32];
57
    /* Special registers */
58
    target_ulong PC;
59
#if TARGET_LONG_BITS > HOST_LONG_BITS
60
    target_ulong t0;
61
    target_ulong t1;
62
    target_ulong t2;
53
typedef union fpr_t fpr_t;
54
union fpr_t {
55
    float64  fd;   /* ieee double precision */
56
    float32  fs[2];/* ieee single precision */
57
    uint64_t d;    /* binary double fixed-point */
58
    uint32_t w[2]; /* binary single fixed-point */
59
};
60
/* define FP_ENDIAN_IDX to access the same location
61
 * in the fpr_t union regardless of the host endianess
62
 */
63
#if defined(WORDS_BIGENDIAN)
64
#  define FP_ENDIAN_IDX 1
65
#else
66
#  define FP_ENDIAN_IDX 0
63 67
#endif
64
    target_ulong HI, LO;
68

  
69
typedef struct CPUMIPSFPUContext CPUMIPSFPUContext;
70
struct CPUMIPSFPUContext {
65 71
    /* Floating point registers */
66 72
    fpr_t fpr[32];
67 73
#ifndef USE_HOST_FLOAT_REGS
......
99 105
#define FP_DIV0           8
100 106
#define FP_INVALID        16
101 107
#define FP_UNIMPLEMENTED  32
108
};
109

  
110
typedef struct CPUMIPSMVPContext CPUMIPSMVPContext;
111
struct CPUMIPSMVPContext {
112
    int32_t CP0_MVPControl;
113
#define CP0MVPCo_CPA	3
114
#define CP0MVPCo_STLB	2
115
#define CP0MVPCo_VPC	1
116
#define CP0MVPCo_EVP	0
117
    int32_t CP0_MVPConf0;
118
#define CP0MVPC0_M	31
119
#define CP0MVPC0_TLBS	29
120
#define CP0MVPC0_GS	28
121
#define CP0MVPC0_PCP	27
122
#define CP0MVPC0_PTLBE	16
123
#define CP0MVPC0_TCA	15
124
#define CP0MVPC0_PVPE	10
125
#define CP0MVPC0_PTC	0
126
    int32_t CP0_MVPConf1;
127
#define CP0MVPC1_CIM	31
128
#define CP0MVPC1_CIF	30
129
#define CP0MVPC1_PCX	20
130
#define CP0MVPC1_PCP2	10
131
#define CP0MVPC1_PCP1	0
132
};
133

  
134
typedef struct mips_def_t mips_def_t;
135

  
136
#define MIPS_SHADOW_SET_MAX 16
137
#define MIPS_TC_MAX 5
138
#define MIPS_DSP_ACC 4
139

  
140
typedef struct CPUMIPSState CPUMIPSState;
141
struct CPUMIPSState {
142
    /* General integer registers */
143
    target_ulong gpr[32][MIPS_SHADOW_SET_MAX];
144
    /* Special registers */
145
    target_ulong PC[MIPS_TC_MAX];
146
#if TARGET_LONG_BITS > HOST_LONG_BITS
147
    target_ulong t0;
148
    target_ulong t1;
149
    target_ulong t2;
150
#endif
151
    target_ulong HI[MIPS_DSP_ACC][MIPS_TC_MAX];
152
    target_ulong LO[MIPS_DSP_ACC][MIPS_TC_MAX];
153
    target_ulong ACX[MIPS_DSP_ACC][MIPS_TC_MAX];
154
    target_ulong DSPControl[MIPS_TC_MAX];
155

  
156
    CPUMIPSMVPContext *mvp;
157
    CPUMIPSTLBContext *tlb;
158
    CPUMIPSFPUContext *fpu;
159
    uint32_t current_tc;
102 160

  
103
    uint32_t nb_tlb;
104
    uint32_t tlb_in_use;
105 161
    uint32_t SEGBITS;
106 162
    target_ulong SEGMask;
107
    int (*map_address) (CPUMIPSState *env, target_ulong *physical, int *prot, target_ulong address, int rw, int access_type);
108
    void (*do_tlbwi) (void);
109
    void (*do_tlbwr) (void);
110
    void (*do_tlbp) (void);
111
    void (*do_tlbr) (void);
112
    union {
113
        struct {
114
            r4k_tlb_t tlb[MIPS_TLB_MAX];
115
        } r4k;
116
    } mmu;
117 163

  
118 164
    int32_t CP0_Index;
165
    /* CP0_MVP* are per MVP registers. */
119 166
    int32_t CP0_Random;
167
    int32_t CP0_VPEControl;
168
#define CP0VPECo_YSI	21
169
#define CP0VPECo_GSI	20
170
#define CP0VPECo_EXCPT	16
171
#define CP0VPECo_TE	15
172
#define CP0VPECo_TargTC	0
173
    int32_t CP0_VPEConf0;
174
#define CP0VPEC0_M	31
175
#define CP0VPEC0_XTC	21
176
#define CP0VPEC0_TCS	19
177
#define CP0VPEC0_SCS	18
178
#define CP0VPEC0_DSC	17
179
#define CP0VPEC0_ICS	16
180
#define CP0VPEC0_MVP	1
181
#define CP0VPEC0_VPA	0
182
    int32_t CP0_VPEConf1;
183
#define CP0VPEC1_NCX	20
184
#define CP0VPEC1_NCP2	10
185
#define CP0VPEC1_NCP1	0
186
    target_ulong CP0_YQMask;
187
    target_ulong CP0_VPESchedule;
188
    target_ulong CP0_VPEScheFBack;
189
    int32_t CP0_VPEOpt;
190
#define CP0VPEOpt_IWX7	15
191
#define CP0VPEOpt_IWX6	14
192
#define CP0VPEOpt_IWX5	13
193
#define CP0VPEOpt_IWX4	12
194
#define CP0VPEOpt_IWX3	11
195
#define CP0VPEOpt_IWX2	10
196
#define CP0VPEOpt_IWX1	9
197
#define CP0VPEOpt_IWX0	8
198
#define CP0VPEOpt_DWX7	7
199
#define CP0VPEOpt_DWX6	6
200
#define CP0VPEOpt_DWX5	5
201
#define CP0VPEOpt_DWX4	4
202
#define CP0VPEOpt_DWX3	3
203
#define CP0VPEOpt_DWX2	2
204
#define CP0VPEOpt_DWX1	1
205
#define CP0VPEOpt_DWX0	0
120 206
    target_ulong CP0_EntryLo0;
207
    int32_t CP0_TCStatus[MIPS_TC_MAX];
208
#define CP0TCSt_TCU3	31
209
#define CP0TCSt_TCU2	30
210
#define CP0TCSt_TCU1	29
211
#define CP0TCSt_TCU0	28
212
#define CP0TCSt_TMX	27
213
#define CP0TCSt_RNST	23
214
#define CP0TCSt_TDS	21
215
#define CP0TCSt_DT	20
216
#define CP0TCSt_DA	15
217
#define CP0TCSt_A	13
218
#define CP0TCSt_TKSU	11
219
#define CP0TCSt_IXMT	10
220
#define CP0TCSt_TASID	0
221
    int32_t CP0_TCBind[MIPS_TC_MAX];
222
#define CP0TCBd_CurTC	21
223
#define CP0TCBd_TBE	17
224
#define CP0TCBd_CurVPE	0
225
    target_ulong CP0_TCHalt[MIPS_TC_MAX];
226
    target_ulong CP0_TCContext[MIPS_TC_MAX];
227
    target_ulong CP0_TCSchedule[MIPS_TC_MAX];
228
    target_ulong CP0_TCScheFBack[MIPS_TC_MAX];
121 229
    target_ulong CP0_EntryLo1;
122 230
    target_ulong CP0_Context;
123 231
    int32_t CP0_PageMask;
124 232
    int32_t CP0_PageGrain;
125 233
    int32_t CP0_Wired;
234
    int32_t CP0_SRSConf0_rw_bitmask;
235
    int32_t CP0_SRSConf0;
236
#define CP0SRSC0_M	31
237
#define CP0SRSC0_SRS3	20
238
#define CP0SRSC0_SRS2	10
239
#define CP0SRSC0_SRS1	0
240
    int32_t CP0_SRSConf1_rw_bitmask;
241
    int32_t CP0_SRSConf1;
242
#define CP0SRSC1_M	31
243
#define CP0SRSC1_SRS6	20
244
#define CP0SRSC1_SRS5	10
245
#define CP0SRSC1_SRS4	0
246
    int32_t CP0_SRSConf2_rw_bitmask;
247
    int32_t CP0_SRSConf2;
248
#define CP0SRSC2_M	31
249
#define CP0SRSC2_SRS9	20
250
#define CP0SRSC2_SRS8	10
251
#define CP0SRSC2_SRS7	0
252
    int32_t CP0_SRSConf3_rw_bitmask;
253
    int32_t CP0_SRSConf3;
254
#define CP0SRSC3_M	31
255
#define CP0SRSC3_SRS12	20
256
#define CP0SRSC3_SRS11	10
257
#define CP0SRSC3_SRS10	0
258
    int32_t CP0_SRSConf4_rw_bitmask;
259
    int32_t CP0_SRSConf4;
260
#define CP0SRSC4_SRS15	20
261
#define CP0SRSC4_SRS14	10
262
#define CP0SRSC4_SRS13	0
126 263
    int32_t CP0_HWREna;
127 264
    target_ulong CP0_BadVAddr;
128 265
    int32_t CP0_Count;
......
152 289
#define CP0St_EXL   1
153 290
#define CP0St_IE    0
154 291
    int32_t CP0_IntCtl;
292
#define CP0IntCtl_IPTI 29
293
#define CP0IntCtl_IPPC1 26
294
#define CP0IntCtl_VS 5
155 295
    int32_t CP0_SRSCtl;
296
#define CP0SRSCtl_HSS 26
297
#define CP0SRSCtl_EICSS 18
298
#define CP0SRSCtl_ESS 12
299
#define CP0SRSCtl_PSS 6
300
#define CP0SRSCtl_CSS 0
156 301
    int32_t CP0_SRSMap;
302
#define CP0SRSMap_SSV7 28
303
#define CP0SRSMap_SSV6 24
304
#define CP0SRSMap_SSV5 20
305
#define CP0SRSMap_SSV4 16
306
#define CP0SRSMap_SSV3 12
307
#define CP0SRSMap_SSV2 8
308
#define CP0SRSMap_SSV1 4
309
#define CP0SRSMap_SSV0 0
157 310
    int32_t CP0_Cause;
158 311
#define CP0Ca_BD   31
159 312
#define CP0Ca_TI   30
......
219 372
#define CP0C3_TL   0
220 373
    int32_t CP0_Config6;
221 374
    int32_t CP0_Config7;
375
    /* XXX: Maybe make LLAddr per-TC? */
222 376
    target_ulong CP0_LLAddr;
223 377
    target_ulong CP0_WatchLo[8];
224 378
    int32_t CP0_WatchHi[8];
225 379
    target_ulong CP0_XContext;
226 380
    int32_t CP0_Framemask;
227 381
    int32_t CP0_Debug;
228
#define CPDB_DBD   31
382
#define CP0DB_DBD  31
229 383
#define CP0DB_DM   30
230 384
#define CP0DB_LSNM 28
231 385
#define CP0DB_Doze 27
......
243 397
#define CP0DB_DDBL 2
244 398
#define CP0DB_DBp  1
245 399
#define CP0DB_DSS  0
400
    int32_t CP0_Debug_tcstatus[MIPS_TC_MAX];
246 401
    target_ulong CP0_DEPC;
247 402
    int32_t CP0_Performance0;
248 403
    int32_t CP0_TagLo;
......
284 439

  
285 440
    int SYNCI_Step; /* Address step size for SYNCI */
286 441
    int CCRes; /* Cycle count resolution/divisor */
287
    int Status_rw_bitmask; /* Read/write bits in CP0_Status */
442
    uint32_t CP0_Status_rw_bitmask; /* Read/write bits in CP0_Status */
443
    uint32_t CP0_TCStatus_rw_bitmask; /* Read/write bits in CP0_TCStatus */
288 444

  
289 445
#ifdef CONFIG_USER_ONLY
290 446
    target_ulong tls_value;
......
376 532
    EXCP_TLBS,
377 533
    EXCP_DBE,
378 534
    EXCP_DDBL,
535
    EXCP_THREAD,
379 536
    EXCP_MTCP0         = 0x104, /* mtmsr instruction:               */
380 537
                                /* may change privilege level       */
381 538
    EXCP_BRANCH        = 0x108, /* branch instruction               */
b/target-mips/exec.h
23 23
#if defined (USE_HOST_FLOAT_REGS)
24 24
#error "implement me."
25 25
#else
26
#define FDT0 (env->ft0.fd)
27
#define FDT1 (env->ft1.fd)
28
#define FDT2 (env->ft2.fd)
29
#define FST0 (env->ft0.fs[FP_ENDIAN_IDX])
30
#define FST1 (env->ft1.fs[FP_ENDIAN_IDX])
31
#define FST2 (env->ft2.fs[FP_ENDIAN_IDX])
32
#define FSTH0 (env->ft0.fs[!FP_ENDIAN_IDX])
33
#define FSTH1 (env->ft1.fs[!FP_ENDIAN_IDX])
34
#define FSTH2 (env->ft2.fs[!FP_ENDIAN_IDX])
35
#define DT0 (env->ft0.d)
36
#define DT1 (env->ft1.d)
37
#define DT2 (env->ft2.d)
38
#define WT0 (env->ft0.w[FP_ENDIAN_IDX])
39
#define WT1 (env->ft1.w[FP_ENDIAN_IDX])
40
#define WT2 (env->ft2.w[FP_ENDIAN_IDX])
41
#define WTH0 (env->ft0.w[!FP_ENDIAN_IDX])
42
#define WTH1 (env->ft1.w[!FP_ENDIAN_IDX])
43
#define WTH2 (env->ft2.w[!FP_ENDIAN_IDX])
26
#define FDT0 (env->fpu->ft0.fd)
27
#define FDT1 (env->fpu->ft1.fd)
28
#define FDT2 (env->fpu->ft2.fd)
29
#define FST0 (env->fpu->ft0.fs[FP_ENDIAN_IDX])
30
#define FST1 (env->fpu->ft1.fs[FP_ENDIAN_IDX])
31
#define FST2 (env->fpu->ft2.fs[FP_ENDIAN_IDX])
32
#define FSTH0 (env->fpu->ft0.fs[!FP_ENDIAN_IDX])
33
#define FSTH1 (env->fpu->ft1.fs[!FP_ENDIAN_IDX])
34
#define FSTH2 (env->fpu->ft2.fs[!FP_ENDIAN_IDX])
35
#define DT0 (env->fpu->ft0.d)
36
#define DT1 (env->fpu->ft1.d)
37
#define DT2 (env->fpu->ft2.d)
38
#define WT0 (env->fpu->ft0.w[FP_ENDIAN_IDX])
39
#define WT1 (env->fpu->ft1.w[FP_ENDIAN_IDX])
40
#define WT2 (env->fpu->ft2.w[FP_ENDIAN_IDX])
41
#define WTH0 (env->fpu->ft0.w[!FP_ENDIAN_IDX])
42
#define WTH1 (env->fpu->ft1.w[!FP_ENDIAN_IDX])
43
#define WTH2 (env->fpu->ft2.w[!FP_ENDIAN_IDX])
44 44
#endif
45 45

  
46 46
#if defined (DEBUG_OP)
......
157 157
void cpu_mips_clock_init (CPUState *env);
158 158
void cpu_mips_tlb_flush (CPUState *env, int flush_global);
159 159

  
160
void do_ctc1 (void);
160
void do_cfc1 (int reg);
161
void do_ctc1 (int reg);
161 162

  
162 163
#define FOP_PROTO(op)              \
163 164
void do_float_ ## op ## _s(void);  \
b/target-mips/fop_template.c
24 24
#define OP_WLOAD_FREG(treg, tregname, FREG)              \
25 25
    void glue(glue(op_load_fpr_,tregname), FREG) (void)  \
26 26
    {                                                    \
27
        treg = env->fpr[FREG].fs[FP_ENDIAN_IDX];         \
27
        treg = env->fpu->fpr[FREG].fs[FP_ENDIAN_IDX];    \
28 28
        RETURN();                                        \
29 29
    }
30 30

  
31 31
#define OP_WSTORE_FREG(treg, tregname, FREG)             \
32 32
    void glue(glue(op_store_fpr_,tregname), FREG) (void) \
33 33
    {                                                    \
34
        env->fpr[FREG].fs[FP_ENDIAN_IDX] = treg;         \
34
        env->fpu->fpr[FREG].fs[FP_ENDIAN_IDX] = treg;    \
35 35
        RETURN();                                        \
36 36
    }
37 37

  
......
50 50
    void glue(glue(op_load_fpr_,tregname), FREG) (void)  \
51 51
    {                                                    \
52 52
        if (env->hflags & MIPS_HFLAG_F64)                \
53
            treg = env->fpr[FREG].fd;                    \
53
            treg = env->fpu->fpr[FREG].fd;               \
54 54
        else                                             \
55
            treg = (uint64_t)(env->fpr[FREG | 1].fs[FP_ENDIAN_IDX]) << 32 | \
56
                   env->fpr[FREG & ~1].fs[FP_ENDIAN_IDX]; \
55
            treg = (uint64_t)(env->fpu->fpr[FREG | 1].fs[FP_ENDIAN_IDX]) << 32 | \
56
                   env->fpu->fpr[FREG & ~1].fs[FP_ENDIAN_IDX]; \
57 57
        RETURN();                                        \
58 58
    }
59 59

  
......
61 61
    void glue(glue(op_store_fpr_,tregname), FREG) (void) \
62 62
    {                                                    \
63 63
        if (env->hflags & MIPS_HFLAG_F64)                \
64
            env->fpr[FREG].fd = treg;                    \
64
            env->fpu->fpr[FREG].fd = treg;               \
65 65
        else {                                           \
66
            env->fpr[FREG | 1].fs[FP_ENDIAN_IDX] = treg >> 32; \
67
            env->fpr[FREG & ~1].fs[FP_ENDIAN_IDX] = treg; \
66
            env->fpu->fpr[FREG | 1].fs[FP_ENDIAN_IDX] = treg >> 32; \
67
            env->fpu->fpr[FREG & ~1].fs[FP_ENDIAN_IDX] = treg;      \
68 68
        }                                                \
69 69
        RETURN();                                        \
70 70
    }
......
81 81
#define OP_PSLOAD_FREG(treg, tregname, FREG)             \
82 82
    void glue(glue(op_load_fpr_,tregname), FREG) (void)  \
83 83
    {                                                    \
84
        treg = env->fpr[FREG].fs[!FP_ENDIAN_IDX];        \
84
        treg = env->fpu->fpr[FREG].fs[!FP_ENDIAN_IDX];   \
85 85
        RETURN();                                        \
86 86
    }
87 87

  
88 88
#define OP_PSSTORE_FREG(treg, tregname, FREG)            \
89 89
    void glue(glue(op_store_fpr_,tregname), FREG) (void) \
90 90
    {                                                    \
91
        env->fpr[FREG].fs[!FP_ENDIAN_IDX] = treg;        \
91
        env->fpu->fpr[FREG].fs[!FP_ENDIAN_IDX] = treg;   \
92 92
        RETURN();                                        \
93 93
    }
94 94

  
b/target-mips/helper.c
70 70
    uint8_t ASID = env->CP0_EntryHi & 0xFF;
71 71
    int i;
72 72

  
73
    for (i = 0; i < env->tlb_in_use; i++) {
74
        r4k_tlb_t *tlb = &env->mmu.r4k.tlb[i];
73
    for (i = 0; i < env->tlb->tlb_in_use; i++) {
74
        r4k_tlb_t *tlb = &env->tlb->mmu.r4k.tlb[i];
75 75
        /* 1k pages are not supported. */
76 76
        target_ulong mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
77 77
        target_ulong tag = address & ~mask;
......
134 134
            *physical = address & 0xFFFFFFFF;
135 135
            *prot = PAGE_READ | PAGE_WRITE;
136 136
        } else {
137
            ret = env->map_address(env, physical, prot, address, rw, access_type);
137
            ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
138 138
        }
139 139
#ifdef TARGET_MIPS64
140 140
/*
......
144 144
    } else if (address < 0x3FFFFFFFFFFFFFFFULL) {
145 145
        /* xuseg */
146 146
	if (UX && address < (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) {
147
            ret = env->map_address(env, physical, prot, address, rw, access_type);
147
            ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
148 148
	} else {
149 149
	    ret = TLBRET_BADADDR;
150 150
        }
151 151
    } else if (address < 0x7FFFFFFFFFFFFFFFULL) {
152 152
        /* xsseg */
153 153
	if (SX && address < (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) {
154
            ret = env->map_address(env, physical, prot, address, rw, access_type);
154
            ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
155 155
	} else {
156 156
	    ret = TLBRET_BADADDR;
157 157
        }
......
169 169
        /* xkseg */
170 170
        /* XXX: check supervisor mode */
171 171
	if (KX && address < (0xFFFFFFFF7FFFFFFFULL & env->SEGMask)) {
172
            ret = env->map_address(env, physical, prot, address, rw, access_type);
172
            ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
173 173
	} else {
174 174
	    ret = TLBRET_BADADDR;
175 175
	}
......
186 186
        *prot = PAGE_READ | PAGE_WRITE;
187 187
    } else if (address < (int32_t)0xE0000000UL) {
188 188
        /* kseg2 */
189
        ret = env->map_address(env, physical, prot, address, rw, access_type);
189
        ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
190 190
    } else {
191 191
        /* kseg3 */
192 192
        /* XXX: check supervisor mode */
193 193
        /* XXX: debug segment is not emulated */
194
        ret = env->map_address(env, physical, prot, address, rw, access_type);
194
        ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
195 195
    }
196 196
#if 0
197 197
    if (logfile) {
......
238 238
        cpu_dump_state(env, logfile, fprintf, 0);
239 239
#endif
240 240
        fprintf(logfile, "%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d is_user %d smmu %d\n",
241
                __func__, env->PC, address, rw, is_user, is_softmmu);
241
                __func__, env->PC[env->current_tc], address, rw, is_user, is_softmmu);
242 242
    }
243 243

  
244 244
    rw &= 1;
......
328 328

  
329 329
    if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) {
330 330
        fprintf(logfile, "%s enter: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d excp %d\n",
331
                __func__, env->PC, env->CP0_EPC, cause, env->exception_index);
331
                __func__, env->PC[env->current_tc], env->CP0_EPC, cause, env->exception_index);
332 332
    }
333 333
    if (env->exception_index == EXCP_EXT_INTERRUPT &&
334 334
        (env->hflags & MIPS_HFLAG_DM))
......
342 342
         * (but we assume the pc has always been updated during
343 343
         *  code translation).
344 344
         */
345
        env->CP0_DEPC = env->PC;
345
        env->CP0_DEPC = env->PC[env->current_tc];
346 346
        goto enter_debug_mode;
347 347
    case EXCP_DINT:
348 348
        env->CP0_Debug |= 1 << CP0DB_DINT;
......
362 362
        if (env->hflags & MIPS_HFLAG_BMASK) {
363 363
            /* If the exception was raised from a delay slot,
364 364
               come back to the jump.  */
365
            env->CP0_DEPC = env->PC - 4;
365
            env->CP0_DEPC = env->PC[env->current_tc] - 4;
366 366
            env->hflags &= ~MIPS_HFLAG_BMASK;
367 367
        } else {
368
            env->CP0_DEPC = env->PC;
368
            env->CP0_DEPC = env->PC[env->current_tc];
369 369
        }
370 370
    enter_debug_mode:
371 371
        env->hflags |= MIPS_HFLAG_DM;
......
375 375
        /* EJTAG probe trap enable is not implemented... */
376 376
        if (!(env->CP0_Status & (1 << CP0St_EXL)))
377 377
            env->CP0_Cause &= ~(1 << CP0Ca_BD);
378
        env->PC = (int32_t)0xBFC00480;
378
        env->PC[env->current_tc] = (int32_t)0xBFC00480;
379 379
        break;
380 380
    case EXCP_RESET:
381 381
        cpu_reset(env);
......
390 390
        if (env->hflags & MIPS_HFLAG_BMASK) {
391 391
            /* If the exception was raised from a delay slot,
392 392
               come back to the jump.  */
393
            env->CP0_ErrorEPC = env->PC - 4;
393
            env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
394 394
            env->hflags &= ~MIPS_HFLAG_BMASK;
395 395
        } else {
396
            env->CP0_ErrorEPC = env->PC;
396
            env->CP0_ErrorEPC = env->PC[env->current_tc];
397 397
        }
398 398
        env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV);
399 399
        if ((env->CP0_Config0 & (0x3 << CP0C0_AT)))
......
401 401
        env->hflags &= ~MIPS_HFLAG_UM;
402 402
        if (!(env->CP0_Status & (1 << CP0St_EXL)))
403 403
            env->CP0_Cause &= ~(1 << CP0Ca_BD);
404
        env->PC = (int32_t)0xBFC00000;
404
        env->PC[env->current_tc] = (int32_t)0xBFC00000;
405 405
        break;
406 406
    case EXCP_MCHECK:
407 407
        cause = 24;
......
471 471
        goto set_EPC;
472 472
    case EXCP_TLBS:
473 473
        cause = 3;
474
        goto set_EPC;
475
    case EXCP_THREAD:
476
        cause = 25;
474 477
        if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) {
475 478
#ifdef TARGET_MIPS64
476 479
            int R = env->CP0_BadVAddr >> 62;
......
489 492
            if (env->hflags & MIPS_HFLAG_BMASK) {
490 493
                /* If the exception was raised from a delay slot,
491 494
                   come back to the jump.  */
492
                env->CP0_EPC = env->PC - 4;
495
                env->CP0_EPC = env->PC[env->current_tc] - 4;
493 496
                env->CP0_Cause |= (1 << CP0Ca_BD);
494 497
            } else {
495
                env->CP0_EPC = env->PC;
498
                env->CP0_EPC = env->PC[env->current_tc];
496 499
                env->CP0_Cause &= ~(1 << CP0Ca_BD);
497 500
            }
498 501
            env->CP0_Status |= (1 << CP0St_EXL);
......
502 505
        }
503 506
        env->hflags &= ~MIPS_HFLAG_BMASK;
504 507
        if (env->CP0_Status & (1 << CP0St_BEV)) {
505
            env->PC = (int32_t)0xBFC00200;
508
            env->PC[env->current_tc] = (int32_t)0xBFC00200;
506 509
        } else {
507
            env->PC = (int32_t)(env->CP0_EBase & ~0x3ff);
510
            env->PC[env->current_tc] = (int32_t)(env->CP0_EBase & ~0x3ff);
508 511
        }
509
        env->PC += offset;
512
        env->PC[env->current_tc] += offset;
510 513
        env->CP0_Cause = (env->CP0_Cause & ~(0x1f << CP0Ca_EC)) | (cause << CP0Ca_EC);
511 514
        break;
512 515
    default:
......
520 523
    if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) {
521 524
        fprintf(logfile, "%s: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d excp %d\n"
522 525
                "    S %08x C %08x A " TARGET_FMT_lx " D " TARGET_FMT_lx "\n",
523
                __func__, env->PC, env->CP0_EPC, cause, env->exception_index,
526
                __func__, env->PC[env->current_tc], env->CP0_EPC, cause, env->exception_index,
524 527
                env->CP0_Status, env->CP0_Cause, env->CP0_BadVAddr,
525 528
                env->CP0_DEPC);
526 529
    }
......
536 539
    uint8_t ASID = env->CP0_EntryHi & 0xFF;
537 540
    target_ulong mask;
538 541

  
539
    tlb = &env->mmu.r4k.tlb[idx];
542
    tlb = &env->tlb->mmu.r4k.tlb[idx];
540 543
    /* The qemu TLB is flushed when the ASID changes, so no need to
541 544
       flush these entries again.  */
542 545
    if (tlb->G == 0 && tlb->ASID != ASID) {
543 546
        return;
544 547
    }
545 548

  
546
    if (use_extra && env->tlb_in_use < MIPS_TLB_MAX) {
549
    if (use_extra && env->tlb->tlb_in_use < MIPS_TLB_MAX) {
547 550
        /* For tlbwr, we can shadow the discarded entry into
548 551
	   a new (fake) TLB entry, as long as the guest can not
549 552
	   tell that it's there.  */
550
        env->mmu.r4k.tlb[env->tlb_in_use] = *tlb;
551
        env->tlb_in_use++;
553
        env->tlb->mmu.r4k.tlb[env->tlb->tlb_in_use] = *tlb;
554
        env->tlb->tlb_in_use++;
552 555
        return;
553 556
    }
554 557

  
b/target-mips/op.c
254 254

  
255 255
void op_load_HI (void)
256 256
{
257
    T0 = env->HI;
257
    T0 = env->HI[PARAM1][env->current_tc];
258 258
    RETURN();
259 259
}
260 260

  
261 261
void op_store_HI (void)
262 262
{
263
    env->HI = T0;
263
    env->HI[PARAM1][env->current_tc] = T0;
264 264
    RETURN();
265 265
}
266 266

  
267 267
void op_load_LO (void)
268 268
{
269
    T0 = env->LO;
269
    T0 = env->LO[PARAM1][env->current_tc];
270 270
    RETURN();
271 271
}
272 272

  
273 273
void op_store_LO (void)
274 274
{
275
    env->LO = T0;
275
    env->LO[PARAM1][env->current_tc] = T0;
276 276
    RETURN();
277 277
}
278 278

  
......
363 363
void op_div (void)
364 364
{
365 365
    if (T1 != 0) {
366
        env->LO = (int32_t)((int64_t)(int32_t)T0 / (int32_t)T1);
367
        env->HI = (int32_t)((int64_t)(int32_t)T0 % (int32_t)T1);
366
        env->LO[0][env->current_tc] = (int32_t)((int64_t)(int32_t)T0 / (int32_t)T1);
367
        env->HI[0][env->current_tc] = (int32_t)((int64_t)(int32_t)T0 % (int32_t)T1);
368 368
    }
369 369
    RETURN();
370 370
}
......
373 373
void op_divu (void)
374 374
{
375 375
    if (T1 != 0) {
376
        env->LO = (int32_t)((uint32_t)T0 / (uint32_t)T1);
377
        env->HI = (int32_t)((uint32_t)T0 % (uint32_t)T1);
376
        env->LO[0][env->current_tc] = (int32_t)((uint32_t)T0 / (uint32_t)T1);
377
        env->HI[0][env->current_tc] = (int32_t)((uint32_t)T0 % (uint32_t)T1);
378 378
    }
379 379
    RETURN();
380 380
}
......
442 442
void op_ddivu (void)
443 443
{
444 444
    if (T1 != 0) {
445
        env->LO = T0 / T1;
446
        env->HI = T0 % T1;
445
        env->LO[0][env->current_tc] = T0 / T1;
446
        env->HI[0][env->current_tc] = T0 % T1;
447 447
    }
448 448
    RETURN();
449 449
}
......
814 814

  
815 815
static inline uint64_t get_HILO (void)
816 816
{
817
    return ((uint64_t)env->HI << 32) | ((uint64_t)(uint32_t)env->LO);
817
    return ((uint64_t)env->HI[0][env->current_tc] << 32) |
818
            ((uint64_t)(uint32_t)env->LO[0][env->current_tc]);
818 819
}
819 820

  
820 821
static inline void set_HILO (uint64_t HILO)
821 822
{
822
    env->LO = (int32_t)(HILO & 0xFFFFFFFF);
823
    env->HI = (int32_t)(HILO >> 32);
823
    env->LO[0][env->current_tc] = (int32_t)(HILO & 0xFFFFFFFF);
824
    env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
824 825
}
825 826

  
826 827
void op_mult (void)
......
875 876
#ifdef TARGET_MIPS64
876 877
void op_dmult (void)
877 878
{
878
    CALL_FROM_TB4(muls64, &(env->HI), &(env->LO), T0, T1);
879
    CALL_FROM_TB4(muls64, &(env->HI[0][env->current_tc]), &(env->LO[0][env->current_tc]), T0, T1);
879 880
    RETURN();
880 881
}
881 882

  
882 883
void op_dmultu (void)
883 884
{
884
    CALL_FROM_TB4(mulu64, &(env->HI), &(env->LO), T0, T1);
885
    CALL_FROM_TB4(mulu64, &(env->HI[0][env->current_tc]), &(env->LO[0][env->current_tc]), T0, T1);
885 886
    RETURN();
886 887
}
887 888
#endif
......
890 891
void op_movn (void)
891 892
{
892 893
    if (T1 != 0)
893
        env->gpr[PARAM1] = T0;
894
        env->gpr[PARAM1][env->current_tc] = T0;
894 895
    RETURN();
895 896
}
896 897

  
897 898
void op_movz (void)
898 899
{
899 900
    if (T1 == 0)
900
        env->gpr[PARAM1] = T0;
901
        env->gpr[PARAM1][env->current_tc] = T0;
901 902
    RETURN();
902 903
}
903 904

  
904 905
void op_movf (void)
905 906
{
906
    if (!(env->fcr31 & PARAM1))
907
    if (!(env->fpu->fcr31 & PARAM1))
907 908
        T0 = T1;
908 909
    RETURN();
909 910
}
910 911

  
911 912
void op_movt (void)
912 913
{
913
    if (env->fcr31 & PARAM1)
914
    if (env->fpu->fcr31 & PARAM1)
914 915
        T0 = T1;
915 916
    RETURN();
916 917
}
......
966 967

  
967 968
void op_breg (void)
968 969
{
969
    env->PC = T2;
970
    env->PC[env->current_tc] = T2;
970 971
    RETURN();
971 972
}
972 973

  
......
1017 1018
    RETURN();
1018 1019
}
1019 1020

  
1021
void op_mfc0_mvpcontrol (void)
1022
{
1023
    T0 = env->mvp->CP0_MVPControl;
1024
    RETURN();
1025
}
1026

  
1027
void op_mfc0_mvpconf0 (void)
1028
{
1029
    T0 = env->mvp->CP0_MVPConf0;
1030
    RETURN();
1031
}
1032

  
1033
void op_mfc0_mvpconf1 (void)
1034
{
1035
    T0 = env->mvp->CP0_MVPConf1;
1036
    RETURN();
1037
}
1038

  
1020 1039
void op_mfc0_random (void)
1021 1040
{
1022 1041
    CALL_FROM_TB0(do_mfc0_random);
1023 1042
    RETURN();
1024 1043
}
1025 1044

  
1045
void op_mfc0_vpecontrol (void)
1046
{
1047
    T0 = env->CP0_VPEControl;
1048
    RETURN();
1049
}
1050

  
1051
void op_mfc0_vpeconf0 (void)
1052
{
1053
    T0 = env->CP0_VPEConf0;
1054
    RETURN();
1055
}
1056

  
1057
void op_mfc0_vpeconf1 (void)
1058
{
1059
    T0 = env->CP0_VPEConf1;
1060
    RETURN();
1061
}
1062

  
1063
void op_mfc0_yqmask (void)
1064
{
1065
    T0 = env->CP0_YQMask;
1066
    RETURN();
1067
}
1068

  
1069
void op_mfc0_vpeschedule (void)
1070
{
1071
    T0 = env->CP0_VPESchedule;
1072
    RETURN();
1073
}
1074

  
1075
void op_mfc0_vpeschefback (void)
1076
{
1077
    T0 = env->CP0_VPEScheFBack;
1078
    RETURN();
1079
}
1080

  
1081
void op_mfc0_vpeopt (void)
1082
{
1083
    T0 = env->CP0_VPEOpt;
1084
    RETURN();
1085
}
1086

  
1026 1087
void op_mfc0_entrylo0 (void)
1027 1088
{
1028 1089
    T0 = (int32_t)env->CP0_EntryLo0;
1029 1090
    RETURN();
1030 1091
}
1031 1092

  
1093
void op_mfc0_tcstatus (void)
1094
{
1095
    T0 = env->CP0_TCStatus[env->current_tc];
1096
    RETURN();
1097
}
1098

  
1099
void op_mftc0_tcstatus(void)
1100
{
1101
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1102

  
1103
    T0 = env->CP0_TCStatus[other_tc];
1104
    RETURN();
1105
}
1106

  
1107
void op_mfc0_tcbind (void)
1108
{
1109
    T0 = env->CP0_TCBind[env->current_tc];
1110
    RETURN();
1111
}
1112

  
1113
void op_mftc0_tcbind(void)
1114
{
1115
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1116

  
1117
    T0 = env->CP0_TCBind[other_tc];
1118
    RETURN();
1119
}
1120

  
1121
void op_mfc0_tcrestart (void)
1122
{
1123
    T0 = env->PC[env->current_tc];
1124
    RETURN();
1125
}
1126

  
1127
void op_mftc0_tcrestart(void)
1128
{
1129
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1130

  
1131
    T0 = env->PC[other_tc];
1132
    RETURN();
1133
}
1134

  
1135
void op_mfc0_tchalt (void)
1136
{
1137
    T0 = env->CP0_TCHalt[env->current_tc];
1138
    RETURN();
1139
}
1140

  
1141
void op_mftc0_tchalt(void)
1142
{
1143
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1144

  
1145
    T0 = env->CP0_TCHalt[other_tc];
1146
    RETURN();
1147
}
1148

  
1149
void op_mfc0_tccontext (void)
1150
{
1151
    T0 = env->CP0_TCContext[env->current_tc];
1152
    RETURN();
1153
}
1154

  
1155
void op_mftc0_tccontext(void)
1156
{
1157
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1158

  
1159
    T0 = env->CP0_TCContext[other_tc];
1160
    RETURN();
1161
}
1162

  
1163
void op_mfc0_tcschedule (void)
1164
{
1165
    T0 = env->CP0_TCSchedule[env->current_tc];
1166
    RETURN();
1167
}
1168

  
1169
void op_mftc0_tcschedule(void)
1170
{
1171
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1172

  
1173
    T0 = env->CP0_TCSchedule[other_tc];
1174
    RETURN();
1175
}
1176

  
1177
void op_mfc0_tcschefback (void)
1178
{
1179
    T0 = env->CP0_TCScheFBack[env->current_tc];
1180
    RETURN();
1181
}
1182

  
1183
void op_mftc0_tcschefback(void)
1184
{
1185
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1186

  
1187
    T0 = env->CP0_TCScheFBack[other_tc];
1188
    RETURN();
1189
}
1190

  
1032 1191
void op_mfc0_entrylo1 (void)
1033 1192
{
1034 1193
    T0 = (int32_t)env->CP0_EntryLo1;
......
1059 1218
    RETURN();
1060 1219
}
1061 1220

  
1221
void op_mfc0_srsconf0 (void)
1222
{
1223
    T0 = env->CP0_SRSConf0;
1224
    RETURN();
1225
}
1226

  
1227
void op_mfc0_srsconf1 (void)
1228
{
1229
    T0 = env->CP0_SRSConf1;
1230
    RETURN();
1231
}
1232

  
1233
void op_mfc0_srsconf2 (void)
1234
{
1235
    T0 = env->CP0_SRSConf2;
1236
    RETURN();
1237
}
1238

  
1239
void op_mfc0_srsconf3 (void)
1240
{
1241
    T0 = env->CP0_SRSConf3;
1242
    RETURN();
1243
}
1244

  
1245
void op_mfc0_srsconf4 (void)
1246
{
1247
    T0 = env->CP0_SRSConf4;
1248
    RETURN();
1249
}
1250

  
1062 1251
void op_mfc0_hwrena (void)
1063 1252
{
1064 1253
    T0 = env->CP0_HWREna;
......
1083 1272
    RETURN();
1084 1273
}
1085 1274

  
1275
void op_mftc0_entryhi(void)
1276
{
1277
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1278

  
1279
    T0 = (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff);
1280
    RETURN();
1281
}
1282

  
1086 1283
void op_mfc0_compare (void)
1087 1284
{
1088 1285
    T0 = env->CP0_Compare;
......
1095 1292
    RETURN();
1096 1293
}
1097 1294

  
1295
void op_mftc0_status(void)
1296
{
1297
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1298
    uint32_t tcstatus = env->CP0_TCStatus[other_tc];
1299

  
1300
    T0 = env->CP0_Status & ~0xf1000018;
1301
    T0 |= tcstatus & (0xf << CP0TCSt_TCU0);
1302
    T0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX);
1303
    T0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_R0);
1304
    RETURN();
1305
}
1306

  
1098 1307
void op_mfc0_intctl (void)
1099 1308
{
1100 1309
    T0 = env->CP0_IntCtl;
......
1211 1420
    RETURN();
1212 1421
}
1213 1422

  
1423
void op_mftc0_debug(void)
1424
{
1425
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1426

  
1427
    /* XXX: Might be wrong, check with EJTAG spec. */
1428
    T0 = (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
1429
         (env->CP0_Debug_tcstatus[other_tc] &
1430
          ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
1431
    RETURN();
1432
}
1433

  
1214 1434
void op_mfc0_depc (void)
1215 1435
{
1216 1436
    T0 = (int32_t)env->CP0_DEPC;
......
1261 1481

  
1262 1482
void op_mtc0_index (void)
1263 1483
{
1264
    env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 % env->nb_tlb);
1484
    env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 % env->tlb->nb_tlb);
1485
    RETURN();
1486
}
1487

  
1488
void op_mtc0_mvpcontrol (void)
1489
{
1490
    uint32_t mask = 0;
1491
    uint32_t newval;
1492

  
1493
    if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))
1494
        mask |= (1 << CP0MVPCo_CPA) | (1 << CP0MVPCo_VPC) |
1495
                (1 << CP0MVPCo_EVP);
1496
    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1497
        mask |= (1 << CP0MVPCo_STLB);
1498
    newval = (env->mvp->CP0_MVPControl & ~mask) | (T0 & mask);
1499

  
1500
    // TODO: Enable/disable shared TLB, enable/disable VPEs.
1501

  
1502
    env->mvp->CP0_MVPControl = newval;
1503
    RETURN();
1504
}
1505

  
1506
void op_mtc0_vpecontrol (void)
1507
{
1508
    uint32_t mask;
1509
    uint32_t newval;
1510

  
1511
    mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
1512
           (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
1513
    newval = (env->CP0_VPEControl & ~mask) | (T0 & mask);
1514

  
1515
    /* Yield scheduler intercept not implemented. */
1516
    /* Gating storage scheduler intercept not implemented. */
1517

  
1518
    // TODO: Enable/disable TCs.
1519

  
1520
    env->CP0_VPEControl = newval;
1521
    RETURN();
1522
}
1523

  
1524
void op_mtc0_vpeconf0 (void)
1525
{
1526
    uint32_t mask = 0;
1527
    uint32_t newval;
1528

  
1529
    if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) {
1530
        if (env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))
1531
            mask |= (0xff << CP0VPEC0_XTC);
1532
        mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
1533
    }
1534
    newval = (env->CP0_VPEConf0 & ~mask) | (T0 & mask);
1535

  
1536
    // TODO: TC exclusive handling due to ERL/EXL.
1537

  
1538
    env->CP0_VPEConf0 = newval;
1539
    RETURN();
1540
}
1541

  
1542
void op_mtc0_vpeconf1 (void)
1543
{
1544
    uint32_t mask = 0;
1545
    uint32_t newval;
1546

  
1547
    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1548
        mask |= (0xff << CP0VPEC1_NCX) | (0xff << CP0VPEC1_NCP2) |
1549
                (0xff << CP0VPEC1_NCP1);
1550
    newval = (env->CP0_VPEConf1 & ~mask) | (T0 & mask);
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff