[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 002/126] tcg: Add TCG_COND_NEVER, TCG_COND_ALWAY
From: |
Aurelien Jarno |
Subject: |
Re: [Qemu-devel] [PATCH 002/126] tcg: Add TCG_COND_NEVER, TCG_COND_ALWAYS |
Date: |
Mon, 10 Sep 2012 16:17:41 +0200 |
User-agent: |
Mutt/1.5.20 (2009-06-14) |
On Sun, Sep 09, 2012 at 02:04:20PM -0700, Richard Henderson wrote:
> There are several cases that can be handled easier inside both
> translators and code generators if we have out-of-band values
> for conditions. It's easy enough to handle ALWAYS and NEVER in
> the natural way inside the tcg middle-end.
>
> Signed-off-by: Richard Henderson <address@hidden>
> Cc: Aurelien Jarno <address@hidden>
> ---
> tcg/arm/tcg-target.c | 2 +-
> tcg/hppa/tcg-target.c | 2 +-
> tcg/i386/tcg-target.c | 2 +-
> tcg/ppc/tcg-target.c | 2 +-
> tcg/ppc64/tcg-target.c | 2 +-
> tcg/s390/tcg-target.c | 6 ++--
> tcg/sparc/tcg-target.c | 2 +-
> tcg/tcg-op.h | 82
> ++++++++++++++++++++++++++++++++++++++------------
> tcg/tcg.c | 2 ++
> tcg/tcg.h | 40 ++++++++++++++++--------
> 10 files changed, 101 insertions(+), 41 deletions(-)
>
> diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
> index cf0ca3d..bb9516c 100644
> --- a/tcg/arm/tcg-target.c
> +++ b/tcg/arm/tcg-target.c
> @@ -342,7 +342,7 @@ enum arm_cond_code_e {
> COND_AL = 0xe,
> };
>
> -static const uint8_t tcg_cond_to_arm_cond[10] = {
> +static const uint8_t tcg_cond_to_arm_cond[] = {
> [TCG_COND_EQ] = COND_EQ,
> [TCG_COND_NE] = COND_NE,
> [TCG_COND_LT] = COND_LT,
> diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
> index 2885212..9cd97d5 100644
> --- a/tcg/hppa/tcg-target.c
> +++ b/tcg/hppa/tcg-target.c
> @@ -738,7 +738,7 @@ static void tcg_out_branch(TCGContext *s, int
> label_index, int nul)
> }
> }
>
> -static const uint8_t tcg_cond_to_cmp_cond[10] =
> +static const uint8_t tcg_cond_to_cmp_cond[] =
> {
> [TCG_COND_EQ] = COND_EQ,
> [TCG_COND_NE] = COND_EQ | COND_FALSE,
> diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
> index da17bba..5dfa113 100644
> --- a/tcg/i386/tcg-target.c
> +++ b/tcg/i386/tcg-target.c
> @@ -338,7 +338,7 @@ static inline int tcg_target_const_match(tcg_target_long
> val,
> #define JCC_JLE 0xe
> #define JCC_JG 0xf
>
> -static const uint8_t tcg_cond_to_jcc[10] = {
> +static const uint8_t tcg_cond_to_jcc[] = {
> [TCG_COND_EQ] = JCC_JE,
> [TCG_COND_NE] = JCC_JNE,
> [TCG_COND_LT] = JCC_JL,
> diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
> index 0cff181..4c70fba 100644
> --- a/tcg/ppc/tcg-target.c
> +++ b/tcg/ppc/tcg-target.c
> @@ -456,7 +456,7 @@ enum {
> CR_SO
> };
>
> -static const uint32_t tcg_to_bc[10] = {
> +static const uint32_t tcg_to_bc[] = {
> [TCG_COND_EQ] = BC | BI (7, CR_EQ) | BO_COND_TRUE,
> [TCG_COND_NE] = BC | BI (7, CR_EQ) | BO_COND_FALSE,
> [TCG_COND_LT] = BC | BI (7, CR_LT) | BO_COND_TRUE,
> diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
> index 27a0ae8..62dff6a 100644
> --- a/tcg/ppc64/tcg-target.c
> +++ b/tcg/ppc64/tcg-target.c
> @@ -428,7 +428,7 @@ enum {
> CR_SO
> };
>
> -static const uint32_t tcg_to_bc[10] = {
> +static const uint32_t tcg_to_bc[] = {
> [TCG_COND_EQ] = BC | BI (7, CR_EQ) | BO_COND_TRUE,
> [TCG_COND_NE] = BC | BI (7, CR_EQ) | BO_COND_FALSE,
> [TCG_COND_LT] = BC | BI (7, CR_LT) | BO_COND_TRUE,
> diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
> index 04662c1..2bffdb2 100644
> --- a/tcg/s390/tcg-target.c
> +++ b/tcg/s390/tcg-target.c
> @@ -268,7 +268,7 @@ static const int tcg_target_call_oarg_regs[] = {
> #define S390_CC_ALWAYS 15
>
> /* Condition codes that result from a COMPARE and COMPARE LOGICAL. */
> -static const uint8_t tcg_cond_to_s390_cond[10] = {
> +static const uint8_t tcg_cond_to_s390_cond[] = {
> [TCG_COND_EQ] = S390_CC_EQ,
> [TCG_COND_NE] = S390_CC_NE,
> [TCG_COND_LT] = S390_CC_LT,
> @@ -284,7 +284,7 @@ static const uint8_t tcg_cond_to_s390_cond[10] = {
> /* Condition codes that result from a LOAD AND TEST. Here, we have no
> unsigned instruction variation, however since the test is vs zero we
> can re-map the outcomes appropriately. */
> -static const uint8_t tcg_cond_to_ltr_cond[10] = {
> +static const uint8_t tcg_cond_to_ltr_cond[] = {
> [TCG_COND_EQ] = S390_CC_EQ,
> [TCG_COND_NE] = S390_CC_NE,
> [TCG_COND_LT] = S390_CC_LT,
> @@ -1138,7 +1138,7 @@ static void tgen64_xori(TCGContext *s, TCGReg dest,
> tcg_target_ulong val)
> static int tgen_cmp(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
> TCGArg c2, int c2const)
> {
> - bool is_unsigned = (c > TCG_COND_GT);
> + bool is_unsigned = is_unsigned_cond(c);
> if (c2const) {
> if (c2 == 0) {
> if (type == TCG_TYPE_I32) {
> diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
> index 247a278..0a25065 100644
> --- a/tcg/sparc/tcg-target.c
> +++ b/tcg/sparc/tcg-target.c
> @@ -510,7 +510,7 @@ static void tcg_out_branch_i64(TCGContext *s, int opc,
> int label_index)
> }
> #endif
>
> -static const uint8_t tcg_cond_to_bcond[10] = {
> +static const uint8_t tcg_cond_to_bcond[] = {
> [TCG_COND_EQ] = COND_E,
> [TCG_COND_NE] = COND_NE,
> [TCG_COND_LT] = COND_L,
> diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
> index 169d3b2..96a30de 100644
> --- a/tcg/tcg-op.h
> +++ b/tcg/tcg-op.h
> @@ -627,29 +627,49 @@ static inline void tcg_gen_sari_i32(TCGv_i32 ret,
> TCGv_i32 arg1, int32_t arg2)
> static inline void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1,
> TCGv_i32 arg2, int label_index)
> {
> - tcg_gen_op4ii_i32(INDEX_op_brcond_i32, arg1, arg2, cond, label_index);
> + if (cond == TCG_COND_ALWAYS) {
> + tcg_gen_br(label_index);
> + } else if (cond != TCG_COND_NEVER) {
> + tcg_gen_op4ii_i32(INDEX_op_brcond_i32, arg1, arg2, cond,
> label_index);
> + }
> }
>
> static inline void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1,
> int32_t arg2, int label_index)
> {
> - TCGv_i32 t0 = tcg_const_i32(arg2);
> - tcg_gen_brcond_i32(cond, arg1, t0, label_index);
> - tcg_temp_free_i32(t0);
> + if (cond == TCG_COND_ALWAYS) {
> + tcg_gen_br(label_index);
> + } else if (cond != TCG_COND_NEVER) {
> + TCGv_i32 t0 = tcg_const_i32(arg2);
> + tcg_gen_brcond_i32(cond, arg1, t0, label_index);
> + tcg_temp_free_i32(t0);
> + }
> }
>
> static inline void tcg_gen_setcond_i32(TCGCond cond, TCGv_i32 ret,
> TCGv_i32 arg1, TCGv_i32 arg2)
> {
> - tcg_gen_op4i_i32(INDEX_op_setcond_i32, ret, arg1, arg2, cond);
> + if (cond == TCG_COND_ALWAYS) {
> + tcg_gen_movi_i32(ret, 1);
> + } else if (cond == TCG_COND_NEVER) {
> + tcg_gen_movi_i32(ret, 0);
> + } else {
> + tcg_gen_op4i_i32(INDEX_op_setcond_i32, ret, arg1, arg2, cond);
> + }
> }
>
> static inline void tcg_gen_setcondi_i32(TCGCond cond, TCGv_i32 ret,
> TCGv_i32 arg1, int32_t arg2)
> {
> - TCGv_i32 t0 = tcg_const_i32(arg2);
> - tcg_gen_setcond_i32(cond, ret, arg1, t0);
> - tcg_temp_free_i32(t0);
> + if (cond == TCG_COND_ALWAYS) {
> + tcg_gen_movi_i32(ret, 1);
> + } else if (cond == TCG_COND_NEVER) {
> + tcg_gen_movi_i32(ret, 0);
> + } else {
> + TCGv_i32 t0 = tcg_const_i32(arg2);
> + tcg_gen_setcond_i32(cond, ret, arg1, t0);
> + tcg_temp_free_i32(t0);
> + }
> }
>
> static inline void tcg_gen_mul_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32
> arg2)
> @@ -945,17 +965,27 @@ static inline void tcg_gen_sari_i64(TCGv_i64 ret,
> TCGv_i64 arg1, int64_t arg2)
> static inline void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1,
> TCGv_i64 arg2, int label_index)
> {
> - tcg_gen_op6ii_i32(INDEX_op_brcond2_i32,
> - TCGV_LOW(arg1), TCGV_HIGH(arg1), TCGV_LOW(arg2),
> - TCGV_HIGH(arg2), cond, label_index);
> + if (cond == TCG_COND_ALWAYS) {
> + tcg_gen_br(label_index);
> + } else if (cond != TCG_COND_NEVER) {
> + tcg_gen_op6ii_i32(INDEX_op_brcond2_i32,
> + TCGV_LOW(arg1), TCGV_HIGH(arg1), TCGV_LOW(arg2),
> + TCGV_HIGH(arg2), cond, label_index);
> + }
> }
>
> static inline void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret,
> TCGv_i64 arg1, TCGv_i64 arg2)
> {
> - tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret),
> - TCGV_LOW(arg1), TCGV_HIGH(arg1),
> - TCGV_LOW(arg2), TCGV_HIGH(arg2), cond);
> + if (cond == TCG_COND_ALWAYS) {
> + tcg_gen_movi_i32(TCGV_LOW(ret), 1);
> + } else if (cond == TCG_COND_NEVER) {
> + tcg_gen_movi_i32(TCGV_LOW(ret), 0);
> + } 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);
> }
>
> @@ -1210,13 +1240,23 @@ static inline void tcg_gen_sari_i64(TCGv_i64 ret,
> TCGv_i64 arg1, int64_t arg2)
> static inline void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1,
> TCGv_i64 arg2, int label_index)
> {
> - tcg_gen_op4ii_i64(INDEX_op_brcond_i64, arg1, arg2, cond, label_index);
> + if (cond == TCG_COND_ALWAYS) {
> + tcg_gen_br(label_index);
> + } else if (cond != TCG_COND_NEVER) {
> + tcg_gen_op4ii_i64(INDEX_op_brcond_i64, arg1, arg2, cond,
> label_index);
> + }
> }
>
> static inline void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret,
> TCGv_i64 arg1, TCGv_i64 arg2)
> {
> - tcg_gen_op4i_i64(INDEX_op_setcond_i64, ret, arg1, arg2, cond);
> + if (cond == TCG_COND_ALWAYS) {
> + tcg_gen_movi_i64(ret, 1);
> + } else if (cond == TCG_COND_NEVER) {
> + tcg_gen_movi_i64(ret, 0);
> + } else {
> + tcg_gen_op4i_i64(INDEX_op_setcond_i64, ret, arg1, arg2, cond);
> + }
> }
>
> static inline void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64
> arg2)
> @@ -1334,9 +1374,13 @@ static inline void tcg_gen_subi_i64(TCGv_i64 ret,
> TCGv_i64 arg1, int64_t arg2)
> static inline void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1,
> int64_t arg2, int label_index)
> {
> - TCGv_i64 t0 = tcg_const_i64(arg2);
> - tcg_gen_brcond_i64(cond, arg1, t0, label_index);
> - tcg_temp_free_i64(t0);
> + if (cond == TCG_COND_ALWAYS) {
> + tcg_gen_br(label_index);
> + } else if (cond != TCG_COND_NEVER) {
> + TCGv_i64 t0 = tcg_const_i64(arg2);
> + tcg_gen_brcond_i64(cond, arg1, t0, label_index);
> + tcg_temp_free_i64(t0);
> + }
> }
>
> static inline void tcg_gen_setcondi_i64(TCGCond cond, TCGv_i64 ret,
> diff --git a/tcg/tcg.c b/tcg/tcg.c
> index 8386b70..42c3b40 100644
> --- a/tcg/tcg.c
> +++ b/tcg/tcg.c
> @@ -861,6 +861,8 @@ static TCGHelperInfo *tcg_find_helper(TCGContext *s,
> tcg_target_ulong val)
>
> static const char * const cond_name[] =
> {
> + [TCG_COND_NEVER] = "never",
> + [TCG_COND_ALWAYS] = "always",
> [TCG_COND_EQ] = "eq",
> [TCG_COND_NE] = "ne",
> [TCG_COND_LT] = "lt",
> diff --git a/tcg/tcg.h b/tcg/tcg.h
> index a9367fe..6c37f15 100644
> --- a/tcg/tcg.h
> +++ b/tcg/tcg.h
> @@ -268,18 +268,28 @@ typedef int TCGv_i64;
> #define TCG_CALL_DUMMY_TCGV MAKE_TCGV_I32(-1)
> #define TCG_CALL_DUMMY_ARG ((TCGArg)(-1))
>
> +/* Conditions. Note that these are layed out for easy manipulation by
> + the the functions below:
> + bit 0 is used for inverting;
> + bit 1 is signed,
> + bit 2 is unsigned,
> + bit 3 is used with bit 0 for swapping signed/unsigned. */
> typedef enum {
> - TCG_COND_EQ,
> - TCG_COND_NE,
> - TCG_COND_LT,
> - TCG_COND_GE,
> - TCG_COND_LE,
> - TCG_COND_GT,
> + /* non-signed */
> + TCG_COND_NEVER = 0 | 0 | 0 | 0,
> + TCG_COND_ALWAYS = 0 | 0 | 0 | 1,
> + TCG_COND_EQ = 8 | 0 | 0 | 0,
> + TCG_COND_NE = 8 | 0 | 0 | 1,
> + /* signed */
> + TCG_COND_LT = 0 | 0 | 2 | 0,
> + TCG_COND_GE = 0 | 0 | 2 | 1,
> + TCG_COND_LE = 8 | 0 | 2 | 0,
> + TCG_COND_GT = 8 | 0 | 2 | 1,
> /* unsigned */
> - TCG_COND_LTU,
> - TCG_COND_GEU,
> - TCG_COND_LEU,
> - TCG_COND_GTU,
> + TCG_COND_LTU = 0 | 4 | 0 | 0,
> + TCG_COND_GEU = 0 | 4 | 0 | 1,
> + TCG_COND_LEU = 8 | 4 | 0 | 0,
> + TCG_COND_GTU = 8 | 4 | 0 | 1,
> } TCGCond;
>
> /* Invert the sense of the comparison. */
> @@ -291,13 +301,17 @@ static inline TCGCond tcg_invert_cond(TCGCond c)
> /* Swap the operands in a comparison. */
> static inline TCGCond tcg_swap_cond(TCGCond c)
> {
> - int mask = (c < TCG_COND_LT ? 0 : c < TCG_COND_LTU ? 7 : 15);
> - return (TCGCond)(c ^ mask);
> + return c & 6 ? (TCGCond)(c ^ 9) : c;
> }
>
> static inline TCGCond tcg_unsigned_cond(TCGCond c)
> {
> - return (c >= TCG_COND_LT && c <= TCG_COND_GT ? c + 4 : c);
> + return c & 2 ? (TCGCond)(c ^ 6) : c;
> +}
> +
> +static inline bool is_unsigned_cond(TCGCond c)
> +{
> + return (c & 4) != 0;
> }
>
> #define TEMP_VAL_DEAD 0
Technically looks fine, but I still don't really fully see the point of
doing that. So I guess:
Reviewed: Aurelien Jarno <address@hidden>
--
Aurelien Jarno GPG: 1024D/F1BCDB73
address@hidden http://www.aurel32.net
- [Qemu-devel] [PATCH 000/126] Rewrite s390x translator, Richard Henderson, 2012/09/09
- [Qemu-devel] [PATCH 001/126] tcg: Add TCGV_IS_UNUSED_*, Richard Henderson, 2012/09/09
- [Qemu-devel] [PATCH 006/126] target-s390: Add missing temp_free in gen_op_calc_cc, Richard Henderson, 2012/09/09
- [Qemu-devel] [PATCH 002/126] tcg: Add TCG_COND_NEVER, TCG_COND_ALWAYS, Richard Henderson, 2012/09/09
- Re: [Qemu-devel] [PATCH 002/126] tcg: Add TCG_COND_NEVER, TCG_COND_ALWAYS,
Aurelien Jarno <=
- [Qemu-devel] [PATCH 004/126] target-s390: Fix disassembly of cpsdr, Richard Henderson, 2012/09/09
- [Qemu-devel] [PATCH 005/126] target-s390: Fix gdbstub, Richard Henderson, 2012/09/09
[Qemu-devel] [PATCH 003/126] target-s390: Disassemble more z10 and z196 opcodes, Richard Henderson, 2012/09/09
[Qemu-devel] [PATCH 007/126] target-s390: Use TCG registers for FPR, Richard Henderson, 2012/09/09