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];
|
pc = env->regs[15];
|
||||||
#elif defined(TARGET_SPARC)
|
#elif defined(TARGET_SPARC)
|
||||||
#ifdef TARGET_SPARC64
|
#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
|
#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
|
#endif
|
||||||
cs_base = env->npc;
|
cs_base = env->npc;
|
||||||
pc = env->pc;
|
pc = env->pc;
|
||||||
|
@ -78,6 +78,8 @@
|
|||||||
#define PS_PRIV (1<<2)
|
#define PS_PRIV (1<<2)
|
||||||
#define PS_IE (1<<1)
|
#define PS_IE (1<<1)
|
||||||
#define PS_AG (1<<0)
|
#define PS_AG (1<<0)
|
||||||
|
|
||||||
|
#define FPRS_FEF (1<<2)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Fcc */
|
/* Fcc */
|
||||||
|
@ -1017,15 +1017,6 @@ void OPPROTO op_trapcc_T0(void)
|
|||||||
FORCE_RET();
|
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)
|
void OPPROTO op_fpexception_im(void)
|
||||||
{
|
{
|
||||||
env->exception_index = TT_FP_EXCP;
|
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 */
|
target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
|
||||||
int is_br;
|
int is_br;
|
||||||
int mem_idx;
|
int mem_idx;
|
||||||
|
int fpu_enabled;
|
||||||
struct TranslationBlock *tb;
|
struct TranslationBlock *tb;
|
||||||
} DisasContext;
|
} DisasContext;
|
||||||
|
|
||||||
@ -935,6 +936,19 @@ static GenOpFunc * const gen_fcmpd[4] = {
|
|||||||
};
|
};
|
||||||
#endif
|
#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 */
|
/* before an instruction, dc->pc must be static */
|
||||||
static void disas_sparc_insn(DisasContext * dc)
|
static void disas_sparc_insn(DisasContext * dc)
|
||||||
{
|
{
|
||||||
@ -981,10 +995,8 @@ static void disas_sparc_insn(DisasContext * dc)
|
|||||||
case 0x5: /* V9 FBPcc */
|
case 0x5: /* V9 FBPcc */
|
||||||
{
|
{
|
||||||
int cc = GET_FIELD_SP(insn, 20, 21);
|
int cc = GET_FIELD_SP(insn, 20, 21);
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
if (gen_trap_ifnofpu(dc))
|
||||||
save_state(dc);
|
goto jmp_insn;
|
||||||
gen_op_trap_ifnofpu();
|
|
||||||
#endif
|
|
||||||
target = GET_FIELD_SP(insn, 0, 18);
|
target = GET_FIELD_SP(insn, 0, 18);
|
||||||
target = sign_extend(target, 19);
|
target = sign_extend(target, 19);
|
||||||
target <<= 2;
|
target <<= 2;
|
||||||
@ -1002,10 +1014,8 @@ static void disas_sparc_insn(DisasContext * dc)
|
|||||||
}
|
}
|
||||||
case 0x6: /* FBN+x */
|
case 0x6: /* FBN+x */
|
||||||
{
|
{
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
if (gen_trap_ifnofpu(dc))
|
||||||
save_state(dc);
|
goto jmp_insn;
|
||||||
gen_op_trap_ifnofpu();
|
|
||||||
#endif
|
|
||||||
target = GET_FIELD(insn, 10, 31);
|
target = GET_FIELD(insn, 10, 31);
|
||||||
target = sign_extend(target, 22);
|
target = sign_extend(target, 22);
|
||||||
target <<= 2;
|
target <<= 2;
|
||||||
@ -1079,16 +1089,16 @@ static void disas_sparc_insn(DisasContext * dc)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
save_state(dc);
|
|
||||||
cond = GET_FIELD(insn, 3, 6);
|
cond = GET_FIELD(insn, 3, 6);
|
||||||
if (cond == 0x8) {
|
if (cond == 0x8) {
|
||||||
|
save_state(dc);
|
||||||
gen_op_trap_T0();
|
gen_op_trap_T0();
|
||||||
dc->is_br = 1;
|
|
||||||
goto jmp_insn;
|
|
||||||
} else if (cond != 0) {
|
} else if (cond != 0) {
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
/* V9 icc/xcc */
|
/* V9 icc/xcc */
|
||||||
int cc = GET_FIELD_SP(insn, 11, 12);
|
int cc = GET_FIELD_SP(insn, 11, 12);
|
||||||
|
flush_T2(dc);
|
||||||
|
save_state(dc);
|
||||||
if (cc == 0)
|
if (cc == 0)
|
||||||
gen_cond[0][cond]();
|
gen_cond[0][cond]();
|
||||||
else if (cc == 2)
|
else if (cc == 2)
|
||||||
@ -1096,10 +1106,17 @@ static void disas_sparc_insn(DisasContext * dc)
|
|||||||
else
|
else
|
||||||
goto illegal_insn;
|
goto illegal_insn;
|
||||||
#else
|
#else
|
||||||
|
flush_T2(dc);
|
||||||
|
save_state(dc);
|
||||||
gen_cond[0][cond]();
|
gen_cond[0][cond]();
|
||||||
#endif
|
#endif
|
||||||
gen_op_trapcc_T0();
|
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) {
|
} else if (xop == 0x28) {
|
||||||
rs1 = GET_FIELD(insn, 13, 17);
|
rs1 = GET_FIELD(insn, 13, 17);
|
||||||
switch(rs1) {
|
switch(rs1) {
|
||||||
@ -1241,10 +1258,8 @@ static void disas_sparc_insn(DisasContext * dc)
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
} else if (xop == 0x34) { /* FPU Operations */
|
} else if (xop == 0x34) { /* FPU Operations */
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
if (gen_trap_ifnofpu(dc))
|
||||||
save_state(dc);
|
goto jmp_insn;
|
||||||
gen_op_trap_ifnofpu();
|
|
||||||
#endif
|
|
||||||
rs1 = GET_FIELD(insn, 13, 17);
|
rs1 = GET_FIELD(insn, 13, 17);
|
||||||
rs2 = GET_FIELD(insn, 27, 31);
|
rs2 = GET_FIELD(insn, 27, 31);
|
||||||
xop = GET_FIELD(insn, 18, 26);
|
xop = GET_FIELD(insn, 18, 26);
|
||||||
@ -1430,10 +1445,8 @@ static void disas_sparc_insn(DisasContext * dc)
|
|||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
int cond;
|
int cond;
|
||||||
#endif
|
#endif
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
if (gen_trap_ifnofpu(dc))
|
||||||
save_state(dc);
|
goto jmp_insn;
|
||||||
gen_op_trap_ifnofpu();
|
|
||||||
#endif
|
|
||||||
rs1 = GET_FIELD(insn, 13, 17);
|
rs1 = GET_FIELD(insn, 13, 17);
|
||||||
rs2 = GET_FIELD(insn, 27, 31);
|
rs2 = GET_FIELD(insn, 27, 31);
|
||||||
xop = GET_FIELD(insn, 18, 26);
|
xop = GET_FIELD(insn, 18, 26);
|
||||||
@ -2366,10 +2379,8 @@ static void disas_sparc_insn(DisasContext * dc)
|
|||||||
skip_move: ;
|
skip_move: ;
|
||||||
#endif
|
#endif
|
||||||
} else if (xop >= 0x20 && xop < 0x24) {
|
} else if (xop >= 0x20 && xop < 0x24) {
|
||||||
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
|
if (gen_trap_ifnofpu(dc))
|
||||||
save_state(dc);
|
goto jmp_insn;
|
||||||
gen_op_trap_ifnofpu();
|
|
||||||
#endif
|
|
||||||
switch (xop) {
|
switch (xop) {
|
||||||
case 0x20: /* load fpreg */
|
case 0x20: /* load fpreg */
|
||||||
gen_op_ldst(ldf);
|
gen_op_ldst(ldf);
|
||||||
@ -2450,9 +2461,8 @@ static void disas_sparc_insn(DisasContext * dc)
|
|||||||
goto illegal_insn;
|
goto illegal_insn;
|
||||||
}
|
}
|
||||||
} else if (xop > 0x23 && xop < 0x28) {
|
} else if (xop > 0x23 && xop < 0x28) {
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
if (gen_trap_ifnofpu(dc))
|
||||||
gen_op_trap_ifnofpu();
|
goto jmp_insn;
|
||||||
#endif
|
|
||||||
switch (xop) {
|
switch (xop) {
|
||||||
case 0x24:
|
case 0x24:
|
||||||
gen_op_load_fpr_FT0(rd);
|
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;
|
dc->npc = (target_ulong) tb->cs_base;
|
||||||
#if defined(CONFIG_USER_ONLY)
|
#if defined(CONFIG_USER_ONLY)
|
||||||
dc->mem_idx = 0;
|
dc->mem_idx = 0;
|
||||||
|
dc->fpu_enabled = 1;
|
||||||
#else
|
#else
|
||||||
dc->mem_idx = ((env->psrs) != 0);
|
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
|
#endif
|
||||||
gen_opc_ptr = gen_opc_buf;
|
gen_opc_ptr = gen_opc_buf;
|
||||||
gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
|
gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
|
||||||
|
Loading…
Reference in New Issue
Block a user