tcg: generic support for conditional set

Defines setcond_{i32,i64} and setcond2_i32 for 64-on-32-bit.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
master
Richard Henderson 2010-01-07 10:13:31 -08:00 committed by Aurelien Jarno
parent a38e609c46
commit be210acb41
4 changed files with 78 additions and 6 deletions

View File

@ -282,6 +282,14 @@ order bytes must be set to zero.
Indicate that the value of t0 won't be used later. It is useful to Indicate that the value of t0 won't be used later. It is useful to
force dead code elimination. force dead code elimination.
********* Conditional moves
* setcond_i32/i64 cond, dest, t1, t2
dest = (t1 cond t2)
Set DEST to 1 if (T1 cond T2) is true, otherwise set to 0.
********* Type conversions ********* Type conversions
* ext_i32_i64 t0, t1 * ext_i32_i64 t0, t1
@ -346,6 +354,11 @@ is returned in two 32-bit outputs.
Similar to mul, except two 32-bit (unsigned) inputs T1 and T2 yielding Similar to mul, except two 32-bit (unsigned) inputs T1 and T2 yielding
the full 64-bit product T0. The later is returned in two 32-bit outputs. the full 64-bit product T0. The later is returned in two 32-bit outputs.
* setcond2_i32 cond, dest, t1_low, t1_high, t2_low, t2_high
Similar to setcond, except that the 64-bit values T1 and T2 are
formed from two 32-bit arguments. The result is a 32-bit value.
********* QEMU specific operations ********* QEMU specific operations
* tb_exit t0 * tb_exit t0

View File

@ -280,6 +280,32 @@ static inline void tcg_gen_op6_i64(int opc, TCGv_i64 arg1, TCGv_i64 arg2,
*gen_opparam_ptr++ = GET_TCGV_I64(arg6); *gen_opparam_ptr++ = GET_TCGV_I64(arg6);
} }
static inline void tcg_gen_op6i_i32(int opc, TCGv_i32 arg1, TCGv_i32 arg2,
TCGv_i32 arg3, TCGv_i32 arg4,
TCGv_i32 arg5, TCGArg arg6)
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = GET_TCGV_I32(arg1);
*gen_opparam_ptr++ = GET_TCGV_I32(arg2);
*gen_opparam_ptr++ = GET_TCGV_I32(arg3);
*gen_opparam_ptr++ = GET_TCGV_I32(arg4);
*gen_opparam_ptr++ = GET_TCGV_I32(arg5);
*gen_opparam_ptr++ = arg6;
}
static inline void tcg_gen_op6i_i64(int opc, TCGv_i64 arg1, TCGv_i64 arg2,
TCGv_i64 arg3, TCGv_i64 arg4,
TCGv_i64 arg5, TCGArg arg6)
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = GET_TCGV_I64(arg1);
*gen_opparam_ptr++ = GET_TCGV_I64(arg2);
*gen_opparam_ptr++ = GET_TCGV_I64(arg3);
*gen_opparam_ptr++ = GET_TCGV_I64(arg4);
*gen_opparam_ptr++ = GET_TCGV_I64(arg5);
*gen_opparam_ptr++ = arg6;
}
static inline void tcg_gen_op6ii_i32(int opc, TCGv_i32 arg1, TCGv_i32 arg2, static inline void tcg_gen_op6ii_i32(int opc, TCGv_i32 arg1, TCGv_i32 arg2,
TCGv_i32 arg3, TCGv_i32 arg4, TCGArg arg5, TCGv_i32 arg3, TCGv_i32 arg4, TCGArg arg5,
TCGArg arg6) TCGArg arg6)
@ -1795,6 +1821,25 @@ static inline void tcg_gen_rotri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
} }
} }
static inline void tcg_gen_setcond_i32(int cond, TCGv_i32 ret,
TCGv_i32 arg1, TCGv_i32 arg2)
{
tcg_gen_op4i_i32(INDEX_op_setcond_i32, ret, arg1, arg2, cond);
}
static inline void tcg_gen_setcond_i64(int cond, TCGv_i64 ret,
TCGv_i64 arg1, TCGv_i64 arg2)
{
#if TCG_TARGET_REG_BITS == 64
tcg_gen_op4i_i64(INDEX_op_setcond_i64, ret, arg1, arg2, cond);
#else
tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret),
TCGV_LOW(arg1), TCGV_HIGH(arg1),
TCGV_LOW(arg2), TCGV_HIGH(arg2), cond);
tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
#endif
}
/***************************************/ /***************************************/
/* QEMU specific operations. Their type depend on the QEMU CPU /* QEMU specific operations. Their type depend on the QEMU CPU
type. */ type. */
@ -2067,6 +2112,7 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv addr, int mem_index)
#define tcg_gen_sari_tl tcg_gen_sari_i64 #define tcg_gen_sari_tl tcg_gen_sari_i64
#define tcg_gen_brcond_tl tcg_gen_brcond_i64 #define tcg_gen_brcond_tl tcg_gen_brcond_i64
#define tcg_gen_brcondi_tl tcg_gen_brcondi_i64 #define tcg_gen_brcondi_tl tcg_gen_brcondi_i64
#define tcg_gen_setcond_tl tcg_gen_setcond_i64
#define tcg_gen_mul_tl tcg_gen_mul_i64 #define tcg_gen_mul_tl tcg_gen_mul_i64
#define tcg_gen_muli_tl tcg_gen_muli_i64 #define tcg_gen_muli_tl tcg_gen_muli_i64
#define tcg_gen_div_tl tcg_gen_div_i64 #define tcg_gen_div_tl tcg_gen_div_i64
@ -2137,6 +2183,7 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv addr, int mem_index)
#define tcg_gen_sari_tl tcg_gen_sari_i32 #define tcg_gen_sari_tl tcg_gen_sari_i32
#define tcg_gen_brcond_tl tcg_gen_brcond_i32 #define tcg_gen_brcond_tl tcg_gen_brcond_i32
#define tcg_gen_brcondi_tl tcg_gen_brcondi_i32 #define tcg_gen_brcondi_tl tcg_gen_brcondi_i32
#define tcg_gen_setcond_tl tcg_gen_setcond_i32
#define tcg_gen_mul_tl tcg_gen_mul_i32 #define tcg_gen_mul_tl tcg_gen_mul_i32
#define tcg_gen_muli_tl tcg_gen_muli_i32 #define tcg_gen_muli_tl tcg_gen_muli_i32
#define tcg_gen_div_tl tcg_gen_div_i32 #define tcg_gen_div_tl tcg_gen_div_i32

View File

@ -42,6 +42,7 @@ DEF2(br, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
DEF2(mov_i32, 1, 1, 0, 0) DEF2(mov_i32, 1, 1, 0, 0)
DEF2(movi_i32, 1, 0, 1, 0) DEF2(movi_i32, 1, 0, 1, 0)
DEF2(setcond_i32, 1, 2, 1, 0)
/* load/store */ /* load/store */
DEF2(ld8u_i32, 1, 1, 1, 0) DEF2(ld8u_i32, 1, 1, 1, 0)
DEF2(ld8s_i32, 1, 1, 1, 0) DEF2(ld8s_i32, 1, 1, 1, 0)
@ -82,6 +83,7 @@ DEF2(add2_i32, 2, 4, 0, 0)
DEF2(sub2_i32, 2, 4, 0, 0) DEF2(sub2_i32, 2, 4, 0, 0)
DEF2(brcond2_i32, 0, 4, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS) DEF2(brcond2_i32, 0, 4, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
DEF2(mulu2_i32, 2, 2, 0, 0) DEF2(mulu2_i32, 2, 2, 0, 0)
DEF2(setcond2_i32, 1, 4, 1, 0)
#endif #endif
#ifdef TCG_TARGET_HAS_ext8s_i32 #ifdef TCG_TARGET_HAS_ext8s_i32
DEF2(ext8s_i32, 1, 1, 0, 0) DEF2(ext8s_i32, 1, 1, 0, 0)
@ -111,6 +113,7 @@ DEF2(neg_i32, 1, 1, 0, 0)
#if TCG_TARGET_REG_BITS == 64 #if TCG_TARGET_REG_BITS == 64
DEF2(mov_i64, 1, 1, 0, 0) DEF2(mov_i64, 1, 1, 0, 0)
DEF2(movi_i64, 1, 0, 1, 0) DEF2(movi_i64, 1, 0, 1, 0)
DEF2(setcond_i64, 1, 2, 1, 0)
/* load/store */ /* load/store */
DEF2(ld8u_i64, 1, 1, 1, 0) DEF2(ld8u_i64, 1, 1, 1, 0)
DEF2(ld8s_i64, 1, 1, 1, 0) DEF2(ld8s_i64, 1, 1, 1, 0)

View File

@ -670,6 +670,7 @@ void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
} }
#endif #endif
static void tcg_reg_alloc_start(TCGContext *s) static void tcg_reg_alloc_start(TCGContext *s)
{ {
int i; int i;
@ -888,21 +889,29 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile)
fprintf(outfile, "%s", fprintf(outfile, "%s",
tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++])); tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++]));
} }
if (c == INDEX_op_brcond_i32 switch (c) {
case INDEX_op_brcond_i32:
#if TCG_TARGET_REG_BITS == 32 #if TCG_TARGET_REG_BITS == 32
|| c == INDEX_op_brcond2_i32 case INDEX_op_brcond2_i32:
#elif TCG_TARGET_REG_BITS == 64 #elif TCG_TARGET_REG_BITS == 64
|| c == INDEX_op_brcond_i64 case INDEX_op_brcond_i64:
#endif
case INDEX_op_setcond_i32:
#if TCG_TARGET_REG_BITS == 32
case INDEX_op_setcond2_i32:
#elif TCG_TARGET_REG_BITS == 64
case INDEX_op_setcond_i64:
#endif #endif
) {
if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]])
fprintf(outfile, ",%s", cond_name[args[k++]]); fprintf(outfile, ",%s", cond_name[args[k++]]);
else else
fprintf(outfile, ",$0x%" TCG_PRIlx, args[k++]); fprintf(outfile, ",$0x%" TCG_PRIlx, args[k++]);
i = 1; i = 1;
} break;
else default:
i = 0; i = 0;
break;
}
for(; i < nb_cargs; i++) { for(; i < nb_cargs; i++) {
if (k != 0) if (k != 0)
fprintf(outfile, ","); fprintf(outfile, ",");