SPARC FPU optimization (Blue Swirl)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2023 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									29133e9a0f
								
							
						
					
					
						commit
						a80dde0837
					
				| @ -175,9 +175,13 @@ static inline TranslationBlock *tb_find_fast(void) | ||||
|     pc = env->regs[15]; | ||||
| #elif defined(TARGET_SPARC) | ||||
| #ifdef TARGET_SPARC64 | ||||
|     flags = (env->pstate << 2) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2); | ||||
|     // Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled
 | ||||
|     flags = (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2)) | ||||
|         | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2); | ||||
| #else | ||||
|     flags = env->psrs | ((env->mmuregs[0] & (MMU_E | MMU_NF)) << 1); | ||||
|     // FPU enable . MMU enabled . MMU no-fault . Supervisor
 | ||||
|     flags = (env->psref << 3) | ((env->mmuregs[0] & (MMU_E | MMU_NF)) << 1) | ||||
|         | env->psrs; | ||||
| #endif | ||||
|     cs_base = env->npc; | ||||
|     pc = env->pc; | ||||
|  | ||||
| @ -78,6 +78,8 @@ | ||||
| #define PS_PRIV  (1<<2) | ||||
| #define PS_IE    (1<<1) | ||||
| #define PS_AG    (1<<0) | ||||
| 
 | ||||
| #define FPRS_FEF (1<<2) | ||||
| #endif | ||||
| 
 | ||||
| /* Fcc */ | ||||
|  | ||||
| @ -1017,15 +1017,6 @@ void OPPROTO op_trapcc_T0(void) | ||||
|     FORCE_RET(); | ||||
| } | ||||
| 
 | ||||
| void OPPROTO op_trap_ifnofpu(void) | ||||
| { | ||||
|     if (!env->psref) { | ||||
|         env->exception_index = TT_NFPU_INSN; | ||||
|         cpu_loop_exit(); | ||||
|     } | ||||
|     FORCE_RET(); | ||||
| } | ||||
| 
 | ||||
| void OPPROTO op_fpexception_im(void) | ||||
| { | ||||
|     env->exception_index = TT_FP_EXCP; | ||||
|  | ||||
| @ -52,6 +52,7 @@ typedef struct DisasContext { | ||||
|     target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */ | ||||
|     int is_br; | ||||
|     int mem_idx; | ||||
|     int fpu_enabled; | ||||
|     struct TranslationBlock *tb; | ||||
| } DisasContext; | ||||
| 
 | ||||
| @ -935,6 +936,19 @@ static GenOpFunc * const gen_fcmpd[4] = { | ||||
| }; | ||||
| #endif | ||||
| 
 | ||||
| static int gen_trap_ifnofpu(DisasContext * dc) | ||||
| { | ||||
| #if !defined(CONFIG_USER_ONLY) | ||||
|     if (!dc->fpu_enabled) { | ||||
|         save_state(dc); | ||||
|         gen_op_exception(TT_NFPU_INSN); | ||||
|         dc->is_br = 1; | ||||
|         return 1; | ||||
|     } | ||||
| #endif | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| /* before an instruction, dc->pc must be static */ | ||||
| static void disas_sparc_insn(DisasContext * dc) | ||||
| { | ||||
| @ -981,10 +995,8 @@ static void disas_sparc_insn(DisasContext * dc) | ||||
| 	    case 0x5:		/* V9 FBPcc */ | ||||
| 		{ | ||||
| 		    int cc = GET_FIELD_SP(insn, 20, 21); | ||||
| #if !defined(CONFIG_USER_ONLY) | ||||
| 		    save_state(dc); | ||||
| 		    gen_op_trap_ifnofpu(); | ||||
| #endif | ||||
|                     if (gen_trap_ifnofpu(dc)) | ||||
|                         goto jmp_insn; | ||||
| 		    target = GET_FIELD_SP(insn, 0, 18); | ||||
| 		    target = sign_extend(target, 19); | ||||
| 		    target <<= 2; | ||||
| @ -1002,10 +1014,8 @@ static void disas_sparc_insn(DisasContext * dc) | ||||
| 		} | ||||
| 	    case 0x6:		/* FBN+x */ | ||||
| 		{ | ||||
| #if !defined(CONFIG_USER_ONLY) | ||||
| 		    save_state(dc); | ||||
| 		    gen_op_trap_ifnofpu(); | ||||
| #endif | ||||
|                     if (gen_trap_ifnofpu(dc)) | ||||
|                         goto jmp_insn; | ||||
| 		    target = GET_FIELD(insn, 10, 31); | ||||
| 		    target = sign_extend(target, 22); | ||||
| 		    target <<= 2; | ||||
| @ -1079,16 +1089,16 @@ static void disas_sparc_insn(DisasContext * dc) | ||||
| 		    } | ||||
| #endif | ||||
|                 } | ||||
|                 save_state(dc); | ||||
|                 cond = GET_FIELD(insn, 3, 6); | ||||
|                 if (cond == 0x8) { | ||||
|                     save_state(dc); | ||||
|                     gen_op_trap_T0(); | ||||
|                     dc->is_br = 1; | ||||
|                     goto jmp_insn; | ||||
|                 } else if (cond != 0) { | ||||
| #ifdef TARGET_SPARC64 | ||||
| 		    /* V9 icc/xcc */ | ||||
| 		    int cc = GET_FIELD_SP(insn, 11, 12); | ||||
| 		    flush_T2(dc); | ||||
|                     save_state(dc); | ||||
| 		    if (cc == 0) | ||||
| 			gen_cond[0][cond](); | ||||
| 		    else if (cc == 2) | ||||
| @ -1096,10 +1106,17 @@ static void disas_sparc_insn(DisasContext * dc) | ||||
| 		    else | ||||
| 			goto illegal_insn; | ||||
| #else | ||||
| 		    flush_T2(dc); | ||||
|                     save_state(dc); | ||||
| 		    gen_cond[0][cond](); | ||||
| #endif | ||||
|                     gen_op_trapcc_T0(); | ||||
|                 } | ||||
|                 gen_op_next_insn(); | ||||
|                 gen_op_movl_T0_0(); | ||||
|                 gen_op_exit_tb(); | ||||
|                 dc->is_br = 1; | ||||
|                 goto jmp_insn; | ||||
|             } else if (xop == 0x28) { | ||||
|                 rs1 = GET_FIELD(insn, 13, 17); | ||||
|                 switch(rs1) { | ||||
| @ -1241,10 +1258,8 @@ static void disas_sparc_insn(DisasContext * dc) | ||||
|                 break; | ||||
| #endif | ||||
| 	    } else if (xop == 0x34) {	/* FPU Operations */ | ||||
| #if !defined(CONFIG_USER_ONLY) | ||||
| 		save_state(dc); | ||||
| 		gen_op_trap_ifnofpu(); | ||||
| #endif | ||||
|                 if (gen_trap_ifnofpu(dc)) | ||||
|                     goto jmp_insn; | ||||
|                 rs1 = GET_FIELD(insn, 13, 17); | ||||
| 	        rs2 = GET_FIELD(insn, 27, 31); | ||||
| 	        xop = GET_FIELD(insn, 18, 26); | ||||
| @ -1430,10 +1445,8 @@ static void disas_sparc_insn(DisasContext * dc) | ||||
| #ifdef TARGET_SPARC64 | ||||
| 		int cond; | ||||
| #endif | ||||
| #if !defined(CONFIG_USER_ONLY) | ||||
| 		save_state(dc); | ||||
| 		gen_op_trap_ifnofpu(); | ||||
| #endif | ||||
|                 if (gen_trap_ifnofpu(dc)) | ||||
|                     goto jmp_insn; | ||||
|                 rs1 = GET_FIELD(insn, 13, 17); | ||||
| 	        rs2 = GET_FIELD(insn, 27, 31); | ||||
| 	        xop = GET_FIELD(insn, 18, 26); | ||||
| @ -2366,10 +2379,8 @@ static void disas_sparc_insn(DisasContext * dc) | ||||
| 	    skip_move: ; | ||||
| #endif | ||||
| 	    } else if (xop >= 0x20 && xop < 0x24) { | ||||
| #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64) | ||||
| 		save_state(dc); | ||||
| 		gen_op_trap_ifnofpu(); | ||||
| #endif | ||||
|                 if (gen_trap_ifnofpu(dc)) | ||||
|                     goto jmp_insn; | ||||
| 		switch (xop) { | ||||
| 		case 0x20:	/* load fpreg */ | ||||
| 		    gen_op_ldst(ldf); | ||||
| @ -2450,9 +2461,8 @@ static void disas_sparc_insn(DisasContext * dc) | ||||
| 		    goto illegal_insn; | ||||
| 		} | ||||
| 	    } else if (xop > 0x23 && xop < 0x28) { | ||||
| #if !defined(CONFIG_USER_ONLY) | ||||
| 		gen_op_trap_ifnofpu(); | ||||
| #endif | ||||
|                 if (gen_trap_ifnofpu(dc)) | ||||
|                     goto jmp_insn; | ||||
| 		switch (xop) { | ||||
| 		case 0x24: | ||||
|                     gen_op_load_fpr_FT0(rd); | ||||
| @ -2548,8 +2558,14 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb, | ||||
|     dc->npc = (target_ulong) tb->cs_base; | ||||
| #if defined(CONFIG_USER_ONLY) | ||||
|     dc->mem_idx = 0; | ||||
|     dc->fpu_enabled = 1; | ||||
| #else | ||||
|     dc->mem_idx = ((env->psrs) != 0); | ||||
| #ifdef TARGET_SPARC64 | ||||
|     dc->fpu_enabled = (((env->pstate & PS_PEF) != 0) && ((env->fprs & FPRS_FEF) != 0)); | ||||
| #else | ||||
|     dc->fpu_enabled = ((env->psref) != 0); | ||||
| #endif | ||||
| #endif | ||||
|     gen_opc_ptr = gen_opc_buf; | ||||
|     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 bellard
						bellard