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