MIPS 64-bit FPU support, plus some collateral bugfixes in the
conditional branch handling. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2779 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									8b4af70527
								
							
						
					
					
						commit
						5a5012ecbd
					
				| 
						 | 
				
			
			@ -4,6 +4,7 @@
 | 
			
		|||
  - ds1225y nvram support (Herve Poussineau)
 | 
			
		||||
  - CPU model selection support (J. Mayer, Paul Brook, Herve Poussineau)
 | 
			
		||||
  - Several Sparc fixes (Aurelien Jarno, Blue Swirl)
 | 
			
		||||
  - MIPS 64-bit FPU support (Thiemo Seufer)
 | 
			
		||||
 | 
			
		||||
version 0.9.0:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -575,7 +575,7 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
 | 
			
		|||
      {
 | 
			
		||||
        for (i = 0; i < 32; i++)
 | 
			
		||||
          {
 | 
			
		||||
            *(uint32_t *)ptr = tswapl(FPR_W (env, i));
 | 
			
		||||
            *(uint32_t *)ptr = tswapl(env->fpr[i].fs[FP_ENDIAN_IDX]);
 | 
			
		||||
            ptr += 4;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -637,7 +637,7 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
 | 
			
		|||
      {
 | 
			
		||||
        for (i = 0; i < 32; i++)
 | 
			
		||||
          {
 | 
			
		||||
            FPR_W (env, i) = tswapl(*(uint32_t *)ptr);
 | 
			
		||||
            env->fpr[i].fs[FP_ENDIAN_IDX] = tswapl(*(uint32_t *)ptr);
 | 
			
		||||
            ptr += 4;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,11 +10,12 @@ General
 | 
			
		|||
  when the Qemu FPU emulation is disabled. Also gdb inside the emulated
 | 
			
		||||
  system does not work. Both problems are caused by insufficient
 | 
			
		||||
  handling of self-modifying code.
 | 
			
		||||
- Floating point exception emulation is incomplete.
 | 
			
		||||
 | 
			
		||||
MIPS64
 | 
			
		||||
------
 | 
			
		||||
- No 64bit TLB support
 | 
			
		||||
- no 64bit wide registers for FPU
 | 
			
		||||
- 64bit FPU not fully implemented
 | 
			
		||||
- 64bit mul/div handling broken
 | 
			
		||||
 | 
			
		||||
"Generic" 4Kc system emulation
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ typedef union fpr_t fpr_t;
 | 
			
		|||
union fpr_t {
 | 
			
		||||
    float64  fd;   /* ieee double precision */
 | 
			
		||||
    float32  fs[2];/* ieee single precision */
 | 
			
		||||
    uint64_t d;    /* binary single fixed-point */
 | 
			
		||||
    uint64_t d;    /* binary double fixed-point */
 | 
			
		||||
    uint32_t w[2]; /* binary single fixed-point */
 | 
			
		||||
};
 | 
			
		||||
/* define FP_ENDIAN_IDX to access the same location
 | 
			
		||||
| 
						 | 
				
			
			@ -64,31 +64,35 @@ struct CPUMIPSState {
 | 
			
		|||
    target_ulong HI, LO;
 | 
			
		||||
    /* Floating point registers */
 | 
			
		||||
    fpr_t fpr[32];
 | 
			
		||||
#define FPR(cpu, n) ((fpr_t*)&(cpu)->fpr[(n) / 2])
 | 
			
		||||
#define FPR_FD(cpu, n) (FPR(cpu, n)->fd)
 | 
			
		||||
#define FPR_FS(cpu, n) (FPR(cpu, n)->fs[((n) & 1) ^ FP_ENDIAN_IDX])
 | 
			
		||||
#define FPR_D(cpu, n)  (FPR(cpu, n)->d)
 | 
			
		||||
#define FPR_W(cpu, n)  (FPR(cpu, n)->w[((n) & 1) ^ FP_ENDIAN_IDX])
 | 
			
		||||
 | 
			
		||||
#ifndef USE_HOST_FLOAT_REGS
 | 
			
		||||
    fpr_t ft0;
 | 
			
		||||
    fpr_t ft1;
 | 
			
		||||
    fpr_t ft2;
 | 
			
		||||
#endif
 | 
			
		||||
    float_status fp_status;
 | 
			
		||||
    /* fpu implementation/revision register */
 | 
			
		||||
    /* fpu implementation/revision register (fir) */
 | 
			
		||||
    uint32_t fcr0;
 | 
			
		||||
#define FCR0_F64 22
 | 
			
		||||
#define FCR0_L 21
 | 
			
		||||
#define FCR0_W 20
 | 
			
		||||
#define FCR0_3D 19
 | 
			
		||||
#define FCR0_PS 18
 | 
			
		||||
#define FCR0_D 17
 | 
			
		||||
#define FCR0_S 16
 | 
			
		||||
#define FCR0_PRID 8
 | 
			
		||||
#define FCR0_REV 0
 | 
			
		||||
    /* fcsr */
 | 
			
		||||
    uint32_t fcr31;
 | 
			
		||||
#define SET_FP_COND(reg)     do { (reg) |= (1<<23); } while(0)
 | 
			
		||||
#define CLEAR_FP_COND(reg)   do { (reg) &= ~(1<<23); } while(0)
 | 
			
		||||
#define IS_FP_COND_SET(reg)  (((reg) & (1<<23)) != 0)
 | 
			
		||||
#define GET_FP_CAUSE(reg)    (((reg) >> 12) & 0x3f)
 | 
			
		||||
#define GET_FP_ENABLE(reg)   (((reg) >>  7) & 0x1f)
 | 
			
		||||
#define GET_FP_FLAGS(reg)    (((reg) >>  2) & 0x1f)
 | 
			
		||||
#define SET_FP_CAUSE(reg,v)  do { (reg) = ((reg) & ~(0x3f << 12)) | ((v) << 12); } while(0)
 | 
			
		||||
#define SET_FP_ENABLE(reg,v) do { (reg) = ((reg) & ~(0x1f <<  7)) | ((v) << 7); } while(0)
 | 
			
		||||
#define SET_FP_FLAGS(reg,v)  do { (reg) = ((reg) & ~(0x1f <<  2)) | ((v) << 2); } while(0)
 | 
			
		||||
#define SET_FP_COND(num,env)     do { (env->fcr31) |= ((num) ? (1 << ((num) + 24)) : (1 << ((num) + 23))); } while(0)
 | 
			
		||||
#define CLEAR_FP_COND(num,env)   do { (env->fcr31) &= ~((num) ? (1 << ((num) + 24)) : (1 << ((num) + 23))); } while(0)
 | 
			
		||||
#define IS_FP_COND_SET(num,env)  (((env->fcr31) & ((num) ? (1 << ((num) + 24)) : (1 << ((num) + 23)))) != 0)
 | 
			
		||||
#define GET_FP_CAUSE(reg)        (((reg) >> 12) & 0x3f)
 | 
			
		||||
#define GET_FP_ENABLE(reg)       (((reg) >>  7) & 0x1f)
 | 
			
		||||
#define GET_FP_FLAGS(reg)        (((reg) >>  2) & 0x1f)
 | 
			
		||||
#define SET_FP_CAUSE(reg,v)      do { (reg) = ((reg) & ~(0x3f << 12)) | ((v & 0x3f) << 12); } while(0)
 | 
			
		||||
#define SET_FP_ENABLE(reg,v)     do { (reg) = ((reg) & ~(0x1f <<  7)) | ((v & 0x1f) << 7); } while(0)
 | 
			
		||||
#define SET_FP_FLAGS(reg,v)      do { (reg) = ((reg) & ~(0x1f <<  2)) | ((v & 0x1f) << 2); } while(0)
 | 
			
		||||
#define UPDATE_FP_FLAGS(reg,v)   do { (reg) |= ((v & 0x1f) << 2); } while(0)
 | 
			
		||||
#define FP_INEXACT        1
 | 
			
		||||
#define FP_UNDERFLOW      2
 | 
			
		||||
#define FP_OVERFLOW       4
 | 
			
		||||
| 
						 | 
				
			
			@ -267,6 +271,7 @@ struct CPUMIPSState {
 | 
			
		|||
 | 
			
		||||
    int SYNCI_Step; /* Address step size for SYNCI */
 | 
			
		||||
    int CCRes; /* Cycle count resolution/divisor */
 | 
			
		||||
    int Status_rw_bitmask; /* Read/write bits in CP0_Status */
 | 
			
		||||
 | 
			
		||||
#if defined(CONFIG_USER_ONLY)
 | 
			
		||||
    target_ulong tls_value;
 | 
			
		||||
| 
						 | 
				
			
			@ -330,10 +335,11 @@ enum {
 | 
			
		|||
    EXCP_RI,
 | 
			
		||||
    EXCP_OVERFLOW,
 | 
			
		||||
    EXCP_TRAP,
 | 
			
		||||
    EXCP_FPE,
 | 
			
		||||
    EXCP_DDBS,
 | 
			
		||||
    EXCP_DWATCH,
 | 
			
		||||
    EXCP_LAE,
 | 
			
		||||
    EXCP_SAE, /* 24 */
 | 
			
		||||
    EXCP_LAE, /* 24 */
 | 
			
		||||
    EXCP_SAE,
 | 
			
		||||
    EXCP_LTLBL,
 | 
			
		||||
    EXCP_TLBL,
 | 
			
		||||
    EXCP_TLBS,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,12 +29,18 @@ register target_ulong T2 asm(AREG3);
 | 
			
		|||
#define FST0 (env->ft0.fs[FP_ENDIAN_IDX])
 | 
			
		||||
#define FST1 (env->ft1.fs[FP_ENDIAN_IDX])
 | 
			
		||||
#define FST2 (env->ft2.fs[FP_ENDIAN_IDX])
 | 
			
		||||
#define FSTH0 (env->ft0.fs[!FP_ENDIAN_IDX])
 | 
			
		||||
#define FSTH1 (env->ft1.fs[!FP_ENDIAN_IDX])
 | 
			
		||||
#define FSTH2 (env->ft2.fs[!FP_ENDIAN_IDX])
 | 
			
		||||
#define DT0 (env->ft0.d)
 | 
			
		||||
#define DT1 (env->ft1.d)
 | 
			
		||||
#define DT2 (env->ft2.d)
 | 
			
		||||
#define WT0 (env->ft0.w[FP_ENDIAN_IDX])
 | 
			
		||||
#define WT1 (env->ft1.w[FP_ENDIAN_IDX])
 | 
			
		||||
#define WT2 (env->ft2.w[FP_ENDIAN_IDX])
 | 
			
		||||
#define WTH0 (env->ft0.w[!FP_ENDIAN_IDX])
 | 
			
		||||
#define WTH1 (env->ft1.w[!FP_ENDIAN_IDX])
 | 
			
		||||
#define WTH2 (env->ft2.w[!FP_ENDIAN_IDX])
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined (DEBUG_OP)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,75 +19,103 @@
 | 
			
		|||
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(SFREG)
 | 
			
		||||
#if defined(FREG)
 | 
			
		||||
 | 
			
		||||
#define OP_WLOAD_FREG(treg, tregname, SFREG)      \
 | 
			
		||||
    void glue(glue(op_load_fpr_,tregname), SFREG) (void) \
 | 
			
		||||
    {                                                   \
 | 
			
		||||
        treg = FPR_W(env, SFREG);     \
 | 
			
		||||
        RETURN();                                       \
 | 
			
		||||
#define OP_WLOAD_FREG(treg, tregname, FREG)              \
 | 
			
		||||
    void glue(glue(op_load_fpr_,tregname), FREG) (void)  \
 | 
			
		||||
    {                                                    \
 | 
			
		||||
        treg = env->fpr[FREG].fs[FP_ENDIAN_IDX];         \
 | 
			
		||||
        RETURN();                                        \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#define OP_WSTORE_FREG(treg, tregname, SFREG)            \
 | 
			
		||||
    void glue(glue(op_store_fpr_,tregname), SFREG) (void)\
 | 
			
		||||
    {                                                   \
 | 
			
		||||
        FPR_W(env, SFREG) = treg;     \
 | 
			
		||||
        RETURN();                                       \
 | 
			
		||||
#define OP_WSTORE_FREG(treg, tregname, FREG)             \
 | 
			
		||||
    void glue(glue(op_store_fpr_,tregname), FREG) (void) \
 | 
			
		||||
    {                                                    \
 | 
			
		||||
        env->fpr[FREG].fs[FP_ENDIAN_IDX] = treg;         \
 | 
			
		||||
        RETURN();                                        \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
/* WT0 = SFREG.w: op_load_fpr_WT0_fprSFREG */
 | 
			
		||||
OP_WLOAD_FREG(WT0, WT0_fpr, SFREG)
 | 
			
		||||
/* SFREG.w = WT0: op_store_fpr_WT0_fprSFREG */
 | 
			
		||||
OP_WSTORE_FREG(WT0, WT0_fpr, SFREG)
 | 
			
		||||
/* WT0 = FREG.w: op_load_fpr_WT0_fprFREG */
 | 
			
		||||
OP_WLOAD_FREG(WT0, WT0_fpr, FREG)
 | 
			
		||||
/* FREG.w = WT0: op_store_fpr_WT0_fprFREG */
 | 
			
		||||
OP_WSTORE_FREG(WT0, WT0_fpr, FREG)
 | 
			
		||||
 | 
			
		||||
OP_WLOAD_FREG(WT1, WT1_fpr, SFREG)
 | 
			
		||||
OP_WSTORE_FREG(WT1, WT1_fpr, SFREG)
 | 
			
		||||
OP_WLOAD_FREG(WT1, WT1_fpr, FREG)
 | 
			
		||||
OP_WSTORE_FREG(WT1, WT1_fpr, FREG)
 | 
			
		||||
 | 
			
		||||
OP_WLOAD_FREG(WT2, WT2_fpr, SFREG)
 | 
			
		||||
OP_WSTORE_FREG(WT2, WT2_fpr, SFREG)
 | 
			
		||||
OP_WLOAD_FREG(WT2, WT2_fpr, FREG)
 | 
			
		||||
OP_WSTORE_FREG(WT2, WT2_fpr, FREG)
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(DFREG)
 | 
			
		||||
 | 
			
		||||
#define OP_DLOAD_FREG(treg, tregname, DFREG)      \
 | 
			
		||||
    void glue(glue(op_load_fpr_,tregname), DFREG) (void) \
 | 
			
		||||
    {                                                   \
 | 
			
		||||
        treg = FPR_D(env, DFREG);                    \
 | 
			
		||||
        RETURN();                                       \
 | 
			
		||||
#define OP_DLOAD_FREG(treg, tregname, FREG)              \
 | 
			
		||||
    void glue(glue(op_load_fpr_,tregname), FREG) (void)  \
 | 
			
		||||
    {                                                    \
 | 
			
		||||
        if (env->CP0_Status & (1 << CP0St_FR))           \
 | 
			
		||||
            treg = env->fpr[FREG].fd;                    \
 | 
			
		||||
        else                                             \
 | 
			
		||||
            treg = (uint64_t)(env->fpr[FREG | 1].fs[FP_ENDIAN_IDX]) << 32 | \
 | 
			
		||||
                   env->fpr[FREG & ~1].fs[FP_ENDIAN_IDX]; \
 | 
			
		||||
        RETURN();                                        \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#define OP_DSTORE_FREG(treg, tregname, DFREG)            \
 | 
			
		||||
    void glue(glue(op_store_fpr_,tregname), DFREG) (void)\
 | 
			
		||||
    {                                                   \
 | 
			
		||||
        FPR_D(env, DFREG) = treg;                    \
 | 
			
		||||
        RETURN();                                       \
 | 
			
		||||
#define OP_DSTORE_FREG(treg, tregname, FREG)             \
 | 
			
		||||
    void glue(glue(op_store_fpr_,tregname), FREG) (void) \
 | 
			
		||||
    {                                                    \
 | 
			
		||||
        if (env->CP0_Status & (1 << CP0St_FR))           \
 | 
			
		||||
            env->fpr[FREG].fd = treg;                    \
 | 
			
		||||
        else {                                           \
 | 
			
		||||
            env->fpr[FREG | 1].fs[FP_ENDIAN_IDX] = treg >> 32; \
 | 
			
		||||
            env->fpr[FREG & ~1].fs[FP_ENDIAN_IDX] = treg; \
 | 
			
		||||
        }                                                \
 | 
			
		||||
        RETURN();                                        \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
OP_DLOAD_FREG(DT0, DT0_fpr, DFREG)
 | 
			
		||||
OP_DSTORE_FREG(DT0, DT0_fpr, DFREG)
 | 
			
		||||
OP_DLOAD_FREG(DT0, DT0_fpr, FREG)
 | 
			
		||||
OP_DSTORE_FREG(DT0, DT0_fpr, FREG)
 | 
			
		||||
 | 
			
		||||
OP_DLOAD_FREG(DT1, DT1_fpr, DFREG)
 | 
			
		||||
OP_DSTORE_FREG(DT1, DT1_fpr, DFREG)
 | 
			
		||||
OP_DLOAD_FREG(DT1, DT1_fpr, FREG)
 | 
			
		||||
OP_DSTORE_FREG(DT1, DT1_fpr, FREG)
 | 
			
		||||
 | 
			
		||||
OP_DLOAD_FREG(DT2, DT2_fpr, DFREG)
 | 
			
		||||
OP_DSTORE_FREG(DT2, DT2_fpr, DFREG)
 | 
			
		||||
OP_DLOAD_FREG(DT2, DT2_fpr, FREG)
 | 
			
		||||
OP_DSTORE_FREG(DT2, DT2_fpr, FREG)
 | 
			
		||||
 | 
			
		||||
#define OP_PSLOAD_FREG(treg, tregname, FREG)             \
 | 
			
		||||
    void glue(glue(op_load_fpr_,tregname), FREG) (void)  \
 | 
			
		||||
    {                                                    \
 | 
			
		||||
        treg = env->fpr[FREG].fs[!FP_ENDIAN_IDX];        \
 | 
			
		||||
        RETURN();                                        \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#define OP_PSSTORE_FREG(treg, tregname, FREG)            \
 | 
			
		||||
    void glue(glue(op_store_fpr_,tregname), FREG) (void) \
 | 
			
		||||
    {                                                    \
 | 
			
		||||
        env->fpr[FREG].fs[!FP_ENDIAN_IDX] = treg;        \
 | 
			
		||||
        RETURN();                                        \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
OP_PSLOAD_FREG(WTH0, WTH0_fpr, FREG)
 | 
			
		||||
OP_PSSTORE_FREG(WTH0, WTH0_fpr, FREG)
 | 
			
		||||
 | 
			
		||||
OP_PSLOAD_FREG(WTH1, WTH1_fpr, FREG)
 | 
			
		||||
OP_PSSTORE_FREG(WTH1, WTH1_fpr, FREG)
 | 
			
		||||
 | 
			
		||||
OP_PSLOAD_FREG(WTH2, WTH2_fpr, FREG)
 | 
			
		||||
OP_PSSTORE_FREG(WTH2, WTH2_fpr, FREG)
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined (FTN)
 | 
			
		||||
 | 
			
		||||
#define SET_RESET(treg, tregname)    \
 | 
			
		||||
#define SET_RESET(treg, tregname)        \
 | 
			
		||||
    void glue(op_set, tregname)(void)    \
 | 
			
		||||
    {                                \
 | 
			
		||||
        treg = PARAM1;               \
 | 
			
		||||
        RETURN();                    \
 | 
			
		||||
    }                                \
 | 
			
		||||
    {                                    \
 | 
			
		||||
        treg = PARAM1;                   \
 | 
			
		||||
        RETURN();                        \
 | 
			
		||||
    }                                    \
 | 
			
		||||
    void glue(op_reset, tregname)(void)  \
 | 
			
		||||
    {                                \
 | 
			
		||||
        treg = 0;                    \
 | 
			
		||||
        RETURN();                    \
 | 
			
		||||
    }                                \
 | 
			
		||||
    {                                    \
 | 
			
		||||
        treg = 0;                        \
 | 
			
		||||
        RETURN();                        \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
SET_RESET(WT0, _WT0)
 | 
			
		||||
SET_RESET(WT1, _WT1)
 | 
			
		||||
| 
						 | 
				
			
			@ -95,6 +123,9 @@ SET_RESET(WT2, _WT2)
 | 
			
		|||
SET_RESET(DT0, _DT0)
 | 
			
		||||
SET_RESET(DT1, _DT1)
 | 
			
		||||
SET_RESET(DT2, _DT2)
 | 
			
		||||
SET_RESET(WTH0, _WTH0)
 | 
			
		||||
SET_RESET(WTH1, _WTH1)
 | 
			
		||||
SET_RESET(WTH2, _WTH2)
 | 
			
		||||
 | 
			
		||||
#undef SET_RESET
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -379,6 +379,9 @@ void do_interrupt (CPUState *env)
 | 
			
		|||
    case EXCP_TRAP:
 | 
			
		||||
        cause = 13;
 | 
			
		||||
        goto set_EPC;
 | 
			
		||||
    case EXCP_FPE:
 | 
			
		||||
        cause = 15;
 | 
			
		||||
        goto set_EPC;
 | 
			
		||||
    case EXCP_LTLBL:
 | 
			
		||||
        cause = 1;
 | 
			
		||||
        goto set_EPC;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										934
									
								
								target-mips/op.c
								
								
								
								
							
							
						
						
									
										934
									
								
								target-mips/op.c
								
								
								
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -220,3 +220,35 @@ void glue(op_sdc1, MEMSUFFIX) (void)
 | 
			
		|||
    glue(stq, MEMSUFFIX)(T0, DT0);
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
void glue(op_lwxc1, MEMSUFFIX) (void)
 | 
			
		||||
{
 | 
			
		||||
    WT0 = glue(ldl, MEMSUFFIX)(T0 + T1);
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
void glue(op_swxc1, MEMSUFFIX) (void)
 | 
			
		||||
{
 | 
			
		||||
    glue(stl, MEMSUFFIX)(T0 + T1, WT0);
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
void glue(op_ldxc1, MEMSUFFIX) (void)
 | 
			
		||||
{
 | 
			
		||||
    DT0 = glue(ldq, MEMSUFFIX)(T0 + T1);
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
void glue(op_sdxc1, MEMSUFFIX) (void)
 | 
			
		||||
{
 | 
			
		||||
    glue(stq, MEMSUFFIX)(T0 + T1, DT0);
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
void glue(op_luxc1, MEMSUFFIX) (void)
 | 
			
		||||
{
 | 
			
		||||
    /* XXX: is defined as unaligned */
 | 
			
		||||
    DT0 = glue(ldq, MEMSUFFIX)(T0 + T1);
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
void glue(op_suxc1, MEMSUFFIX) (void)
 | 
			
		||||
{
 | 
			
		||||
    /* XXX: is defined as unaligned */
 | 
			
		||||
    glue(stq, MEMSUFFIX)(T0 + T1, DT0);
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -55,7 +55,7 @@
 | 
			
		|||
 | 
			
		||||
/* Define a implementation number of 1.
 | 
			
		||||
   Define a major version 1, minor version 0. */
 | 
			
		||||
#define MIPS_FCR0 ((0 << 16) | (1 << 8) | (1 << 4) | 0)
 | 
			
		||||
#define MIPS_FCR0 ((0 << FCR0_S) | (0x1 << FCR0_PRID) | (0x10 << FCR0_REV))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct mips_def_t {
 | 
			
		||||
| 
						 | 
				
			
			@ -69,6 +69,7 @@ struct mips_def_t {
 | 
			
		|||
    int32_t CP0_Config7;
 | 
			
		||||
    int32_t SYNCI_Step;
 | 
			
		||||
    int32_t CCRes;
 | 
			
		||||
    int32_t Status_rw_bitmask;
 | 
			
		||||
    int32_t CP1_fcr0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -86,7 +87,7 @@ static mips_def_t mips_defs[] =
 | 
			
		|||
        .CP0_Config3 = MIPS_CONFIG3,
 | 
			
		||||
        .SYNCI_Step = 32,
 | 
			
		||||
        .CCRes = 2,
 | 
			
		||||
        .CP1_fcr0 = MIPS_FCR0,
 | 
			
		||||
        .Status_rw_bitmask = 0x3278FF17,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        .name = "4KEcR1",
 | 
			
		||||
| 
						 | 
				
			
			@ -97,7 +98,6 @@ static mips_def_t mips_defs[] =
 | 
			
		|||
        .CP0_Config3 = MIPS_CONFIG3,
 | 
			
		||||
        .SYNCI_Step = 32,
 | 
			
		||||
        .CCRes = 2,
 | 
			
		||||
        .CP1_fcr0 = MIPS_FCR0,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        .name = "4KEc",
 | 
			
		||||
| 
						 | 
				
			
			@ -108,7 +108,7 @@ static mips_def_t mips_defs[] =
 | 
			
		|||
        .CP0_Config3 = MIPS_CONFIG3,
 | 
			
		||||
        .SYNCI_Step = 32,
 | 
			
		||||
        .CCRes = 2,
 | 
			
		||||
        .CP1_fcr0 = MIPS_FCR0,
 | 
			
		||||
        .Status_rw_bitmask = 0x3278FF17,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        .name = "24Kc",
 | 
			
		||||
| 
						 | 
				
			
			@ -119,7 +119,7 @@ static mips_def_t mips_defs[] =
 | 
			
		|||
        .CP0_Config3 = MIPS_CONFIG3,
 | 
			
		||||
        .SYNCI_Step = 32,
 | 
			
		||||
        .CCRes = 2,
 | 
			
		||||
        .CP1_fcr0 = MIPS_FCR0,
 | 
			
		||||
        .Status_rw_bitmask = 0x3278FF17,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        .name = "24Kf",
 | 
			
		||||
| 
						 | 
				
			
			@ -130,7 +130,9 @@ static mips_def_t mips_defs[] =
 | 
			
		|||
        .CP0_Config3 = MIPS_CONFIG3,
 | 
			
		||||
        .SYNCI_Step = 32,
 | 
			
		||||
        .CCRes = 2,
 | 
			
		||||
        .CP1_fcr0 = MIPS_FCR0,
 | 
			
		||||
        .Status_rw_bitmask = 0x3678FF17,
 | 
			
		||||
        .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
 | 
			
		||||
                    (1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID),
 | 
			
		||||
    },
 | 
			
		||||
#else
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -142,7 +144,10 @@ static mips_def_t mips_defs[] =
 | 
			
		|||
        .CP0_Config3 = MIPS_CONFIG3,
 | 
			
		||||
        .SYNCI_Step = 16,
 | 
			
		||||
        .CCRes = 2,
 | 
			
		||||
        .CP1_fcr0 = MIPS_FCR0,
 | 
			
		||||
        .Status_rw_bitmask = 0x3678FFFF,
 | 
			
		||||
        .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
 | 
			
		||||
                    (1 << FCR0_D) | (1 << FCR0_S) |
 | 
			
		||||
                    (0x4 << FCR0_PRID) | (0x0 << FCR0_REV),
 | 
			
		||||
    },
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -191,6 +196,7 @@ int cpu_mips_register (CPUMIPSState *env, mips_def_t *def)
 | 
			
		|||
    env->CP0_Config7 = def->CP0_Config7;
 | 
			
		||||
    env->SYNCI_Step = def->SYNCI_Step;
 | 
			
		||||
    env->CCRes = def->CCRes;
 | 
			
		||||
    env->Status_rw_bitmask = def->Status_rw_bitmask;
 | 
			
		||||
    env->fcr0 = def->CP1_fcr0;
 | 
			
		||||
#if defined (MIPS_USES_R4K_TLB)
 | 
			
		||||
    env->nb_tlb = 1 + ((def->CP0_Config1 >> CP0C1_MMU) & 63);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue