mirror of
				https://git.proxmox.com/git/qemu
				synced 2025-10-31 07:39:44 +00:00 
			
		
		
		
	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
	
	Block a user
	 ths
						ths