mirror of https://gitee.com/openkylin/qemu.git
Switch MIPS clo/clz and the condition tests to TCG.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4507 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
20c4c97c9b
commit
30898801ad
|
@ -1,3 +1,8 @@
|
|||
void do_raise_exception_err(int excp, int err);
|
||||
void do_raise_exception(int excp);
|
||||
void do_interrupt_restart (void);
|
||||
|
||||
void do_clo (void);
|
||||
void do_clz (void);
|
||||
void do_dclo (void);
|
||||
void do_dclz (void);
|
||||
|
|
|
@ -167,51 +167,6 @@
|
|||
#undef MEMSUFFIX
|
||||
#endif
|
||||
|
||||
/* Logical */
|
||||
void op_clo (void)
|
||||
{
|
||||
T0 = clo32(T0);
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void op_clz (void)
|
||||
{
|
||||
T0 = clz32(T0);
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
#if defined(TARGET_MIPS64)
|
||||
|
||||
#if TARGET_LONG_BITS > HOST_LONG_BITS
|
||||
/* Those might call libgcc functions. */
|
||||
void op_dclo (void)
|
||||
{
|
||||
CALL_FROM_TB0(do_dclo);
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void op_dclz (void)
|
||||
{
|
||||
CALL_FROM_TB0(do_dclz);
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
#else /* TARGET_LONG_BITS > HOST_LONG_BITS */
|
||||
|
||||
void op_dclo (void)
|
||||
{
|
||||
T0 = clo64(T0);
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void op_dclz (void)
|
||||
{
|
||||
T0 = clz64(T0);
|
||||
FORCE_RET();
|
||||
}
|
||||
#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
|
||||
#endif /* TARGET_MIPS64 */
|
||||
|
||||
/* 64 bits arithmetic */
|
||||
#if TARGET_LONG_BITS > HOST_LONG_BITS
|
||||
void op_mult (void)
|
||||
|
@ -524,29 +479,6 @@ void op_movt (void)
|
|||
FORCE_RET();
|
||||
}
|
||||
|
||||
/* Tests */
|
||||
#define OP_COND(name, cond) \
|
||||
void glue(op_, name) (void) \
|
||||
{ \
|
||||
if (cond) { \
|
||||
T0 = 1; \
|
||||
} else { \
|
||||
T0 = 0; \
|
||||
} \
|
||||
FORCE_RET(); \
|
||||
}
|
||||
|
||||
OP_COND(eq, T0 == T1);
|
||||
OP_COND(ne, T0 != T1);
|
||||
OP_COND(ge, (target_long)T0 >= (target_long)T1);
|
||||
OP_COND(geu, T0 >= T1);
|
||||
OP_COND(lt, (target_long)T0 < (target_long)T1);
|
||||
OP_COND(ltu, T0 < T1);
|
||||
OP_COND(gez, (target_long)T0 >= 0);
|
||||
OP_COND(gtz, (target_long)T0 > 0);
|
||||
OP_COND(lez, (target_long)T0 <= 0);
|
||||
OP_COND(ltz, (target_long)T0 < 0);
|
||||
|
||||
/* Branches */
|
||||
/* Branch to register */
|
||||
void op_save_breg_target (void)
|
||||
|
|
|
@ -71,6 +71,16 @@ void do_restore_state (void *pc_ptr)
|
|||
}
|
||||
}
|
||||
|
||||
void do_clo (void)
|
||||
{
|
||||
T0 = clo32(T0);
|
||||
}
|
||||
|
||||
void do_clz (void)
|
||||
{
|
||||
T0 = clz32(T0);
|
||||
}
|
||||
|
||||
#if defined(TARGET_MIPS64)
|
||||
#if TARGET_LONG_BITS > HOST_LONG_BITS
|
||||
/* Those might call libgcc functions. */
|
||||
|
|
|
@ -655,6 +655,65 @@ FOP_CONDS(abs, s)
|
|||
FOP_CONDS(, ps)
|
||||
FOP_CONDS(abs, ps)
|
||||
|
||||
/* Tests */
|
||||
#define OP_COND(name, cond) \
|
||||
void glue(gen_op_, name) (void) \
|
||||
{ \
|
||||
int l1 = gen_new_label(); \
|
||||
int l2 = gen_new_label(); \
|
||||
\
|
||||
tcg_gen_brcond_tl(cond, cpu_T[0], cpu_T[1], l1); \
|
||||
gen_op_set_T0(0); \
|
||||
tcg_gen_br(l2); \
|
||||
gen_set_label(l1); \
|
||||
gen_op_set_T0(1); \
|
||||
gen_set_label(l2); \
|
||||
}
|
||||
OP_COND(eq, TCG_COND_EQ);
|
||||
OP_COND(ne, TCG_COND_NE);
|
||||
OP_COND(ge, TCG_COND_GE);
|
||||
OP_COND(geu, TCG_COND_GEU);
|
||||
OP_COND(lt, TCG_COND_LT);
|
||||
OP_COND(ltu, TCG_COND_LTU);
|
||||
#undef OP_COND
|
||||
|
||||
#define OP_CONDI(name, cond) \
|
||||
void glue(gen_op_, name) (target_ulong val) \
|
||||
{ \
|
||||
int l1 = gen_new_label(); \
|
||||
int l2 = gen_new_label(); \
|
||||
\
|
||||
tcg_gen_brcond_tl(cond, cpu_T[0], tcg_const_tl(val), l1); \
|
||||
gen_op_set_T0(0); \
|
||||
tcg_gen_br(l2); \
|
||||
gen_set_label(l1); \
|
||||
gen_op_set_T0(1); \
|
||||
gen_set_label(l2); \
|
||||
}
|
||||
OP_CONDI(lti, TCG_COND_LT);
|
||||
OP_CONDI(ltiu, TCG_COND_LTU);
|
||||
#undef OP_CONDI
|
||||
|
||||
#define OP_CONDZ(name, cond) \
|
||||
void glue(gen_op_, name) (void) \
|
||||
{ \
|
||||
int l1 = gen_new_label(); \
|
||||
int l2 = gen_new_label(); \
|
||||
\
|
||||
tcg_gen_brcond_tl(cond, cpu_T[0], tcg_const_tl(0), l1); \
|
||||
gen_op_set_T0(0); \
|
||||
tcg_gen_br(l2); \
|
||||
gen_set_label(l1); \
|
||||
gen_op_set_T0(1); \
|
||||
gen_set_label(l2); \
|
||||
}
|
||||
OP_CONDZ(gez, TCG_COND_GE);
|
||||
OP_CONDZ(gtz, TCG_COND_GT);
|
||||
OP_CONDZ(lez, TCG_COND_LE);
|
||||
OP_CONDZ(ltz, TCG_COND_LT);
|
||||
#undef OP_CONDZ
|
||||
|
||||
|
||||
typedef struct DisasContext {
|
||||
struct TranslationBlock *tb;
|
||||
target_ulong pc, saved_pc;
|
||||
|
@ -1375,11 +1434,11 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
|
|||
break;
|
||||
#endif
|
||||
case OPC_SLTI:
|
||||
gen_op_lt();
|
||||
gen_op_lti(uimm);
|
||||
opn = "slti";
|
||||
break;
|
||||
case OPC_SLTIU:
|
||||
gen_op_ltu();
|
||||
gen_op_ltiu(uimm);
|
||||
opn = "sltiu";
|
||||
break;
|
||||
case OPC_ANDI:
|
||||
|
@ -2160,20 +2219,20 @@ static void gen_cl (DisasContext *ctx, uint32_t opc,
|
|||
GEN_LOAD_REG_T0(rs);
|
||||
switch (opc) {
|
||||
case OPC_CLO:
|
||||
gen_op_clo();
|
||||
tcg_gen_helper_0_0(do_clo);
|
||||
opn = "clo";
|
||||
break;
|
||||
case OPC_CLZ:
|
||||
gen_op_clz();
|
||||
tcg_gen_helper_0_0(do_clz);
|
||||
opn = "clz";
|
||||
break;
|
||||
#if defined(TARGET_MIPS64)
|
||||
case OPC_DCLO:
|
||||
gen_op_dclo();
|
||||
tcg_gen_helper_0_0(do_dclo);
|
||||
opn = "dclo";
|
||||
break;
|
||||
case OPC_DCLZ:
|
||||
gen_op_dclz();
|
||||
tcg_gen_helper_0_0(do_dclz);
|
||||
opn = "dclz";
|
||||
break;
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue