qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [5506] target-ppc: convert logical instructions to TCG


From: andrzej zaborowski
Subject: Re: [Qemu-devel] [5506] target-ppc: convert logical instructions to TCG
Date: Thu, 30 Oct 2008 04:10:55 +0100

Hi,

2008/10/21 Aurelien Jarno <address@hidden>:
> Revision: 5506
>          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5506
> Author:   aurel32
> Date:     2008-10-21 11:31:27 +0000 (Tue, 21 Oct 2008)
>
> Log Message:
> -----------
> target-ppc: convert logical instructions to TCG
>
> Signed-off-by: Aurelien Jarno <address@hidden>
>
> Modified Paths:
> --------------
>    trunk/target-ppc/helper.h
>    trunk/target-ppc/op.c
>    trunk/target-ppc/op_helper.c
>    trunk/target-ppc/translate.c
>
> Modified: trunk/target-ppc/helper.h
> ===================================================================
> --- trunk/target-ppc/helper.h   2008-10-21 11:31:14 UTC (rev 5505)
> +++ trunk/target-ppc/helper.h   2008-10-21 11:31:27 UTC (rev 5506)
> @@ -7,3 +7,13 @@
>
>  DEF_HELPER(uint32_t, helper_load_cr, (void))
>  DEF_HELPER(void, helper_store_cr, (target_ulong, uint32_t))
> +
> +DEF_HELPER(target_ulong, helper_cntlzw, (target_ulong t))
> +DEF_HELPER(target_ulong, helper_popcntb, (target_ulong val))
> +DEF_HELPER(target_ulong, helper_sraw, (target_ulong, target_ulong))
> +#if defined(TARGET_PPC64)
> +DEF_HELPER(target_ulong, helper_cntlzd, (target_ulong t))
> +DEF_HELPER(target_ulong, helper_popcntb_64, (target_ulong val))
> +DEF_HELPER(target_ulong, helper_srad, (target_ulong, target_ulong))
> +#endif
> +
>
> Modified: trunk/target-ppc/op.c
> ===================================================================
> --- trunk/target-ppc/op.c       2008-10-21 11:31:14 UTC (rev 5505)
> +++ trunk/target-ppc/op.c       2008-10-21 11:31:27 UTC (rev 5506)
> @@ -37,15 +37,6 @@
>     do_raise_exception(EXCP_DEBUG);
>  }
>
> -/* Load/store special registers */
> -#if defined(TARGET_PPC64)
> -void OPPROTO op_store_pri (void)
> -{
> -    do_store_pri(PARAM1);
> -    RETURN();
> -}
> -#endif
> -
>  #if !defined(CONFIG_USER_ONLY)
>  /* Segment registers load and store */
>  void OPPROTO op_load_sr (void)
> @@ -921,101 +912,7 @@
>  }
>  #endif
>
> -void OPPROTO op_popcntb (void)
> -{
> -    do_popcntb();
> -    RETURN();
> -}
> -
> -#if defined(TARGET_PPC64)
> -void OPPROTO op_popcntb_64 (void)
> -{
> -    do_popcntb_64();
> -    RETURN();
> -}
> -#endif
> -
>  /***                            Integer logical                            
> ***/
> -/* and */
> -void OPPROTO op_and (void)
> -{
> -    T0 &= T1;
> -    RETURN();
> -}
> -
> -/* andc */
> -void OPPROTO op_andc (void)
> -{
> -    T0 &= ~T1;
> -    RETURN();
> -}
> -
> -/* count leading zero */
> -void OPPROTO op_cntlzw (void)
> -{
> -    do_cntlzw();
> -    RETURN();
> -}
> -
> -#if defined(TARGET_PPC64)
> -void OPPROTO op_cntlzd (void)
> -{
> -    do_cntlzd();
> -    RETURN();
> -}
> -#endif
> -
> -/* eqv */
> -void OPPROTO op_eqv (void)
> -{
> -    T0 = ~(T0 ^ T1);
> -    RETURN();
> -}
> -
> -/* extend sign byte */
> -void OPPROTO op_extsb (void)
> -{
> -#if defined (TARGET_PPC64)
> -    T0 = (int64_t)((int8_t)T0);
> -#else
> -    T0 = (int32_t)((int8_t)T0);
> -#endif
> -    RETURN();
> -}
> -
> -/* extend sign half word */
> -void OPPROTO op_extsh (void)
> -{
> -#if defined (TARGET_PPC64)
> -    T0 = (int64_t)((int16_t)T0);
> -#else
> -    T0 = (int32_t)((int16_t)T0);
> -#endif
> -    RETURN();
> -}
> -
> -#if defined (TARGET_PPC64)
> -void OPPROTO op_extsw (void)
> -{
> -    T0 = (int64_t)((int32_t)T0);
> -    RETURN();
> -}
> -#endif
> -
> -/* nand */
> -void OPPROTO op_nand (void)
> -{
> -    T0 = ~(T0 & T1);
> -    RETURN();
> -}
> -
> -/* nor */
> -void OPPROTO op_nor (void)
> -{
> -    T0 = ~(T0 | T1);
> -    RETURN();
> -}
> -
>  /* or */
>  void OPPROTO op_or (void)
>  {
> @@ -1023,34 +920,6 @@
>     RETURN();
>  }
>
> -/* orc */
> -void OPPROTO op_orc (void)
> -{
> -    T0 |= ~T1;
> -    RETURN();
> -}
> -
> -/* ori */
> -void OPPROTO op_ori (void)
> -{
> -    T0 |= (uint32_t)PARAM1;
> -    RETURN();
> -}
> -
> -/* xor */
> -void OPPROTO op_xor (void)
> -{
> -    T0 ^= T1;
> -    RETURN();
> -}
> -
> -/* xori */
> -void OPPROTO op_xori (void)
> -{
> -    T0 ^= (uint32_t)PARAM1;
> -    RETURN();
> -}
> -
>  /***                             Integer rotate                            
> ***/
>  void OPPROTO op_rotl32_T0_T1 (void)
>  {
> @@ -1079,122 +948,13 @@
>  #endif
>
>  /***                             Integer shift                             
> ***/
> -/* shift left word */
> -void OPPROTO op_slw (void)
> -{
> -    if (T1 & 0x20) {
> -        T0 = 0;
> -    } else {
> -        T0 = (uint32_t)(T0 << T1);
> -    }
> -    RETURN();
> -}
> -
> -#if defined(TARGET_PPC64)
> -void OPPROTO op_sld (void)
> -{
> -    if (T1 & 0x40) {
> -        T0 = 0;
> -    } else {
> -        T0 = T0 << T1;
> -    }
> -    RETURN();
> -}
> -#endif
> -
> -/* shift right algebraic word */
> -void OPPROTO op_sraw (void)
> -{
> -    do_sraw();
> -    RETURN();
> -}
> -
> -#if defined(TARGET_PPC64)
> -void OPPROTO op_srad (void)
> -{
> -    do_srad();
> -    RETURN();
> -}
> -#endif
> -
> -/* shift right algebraic word immediate */
> -void OPPROTO op_srawi (void)
> -{
> -    uint32_t mask = (uint32_t)PARAM2;
> -
> -    T0 = (int32_t)T0 >> PARAM1;
> -    if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
> -        env->xer |= (1 << XER_CA);
> -    } else {
> -        env->xer &= ~(1 << XER_CA);
> -    }
> -    RETURN();
> -}
> -
> -#if defined(TARGET_PPC64)
> -void OPPROTO op_sradi (void)
> -{
> -    uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
> -
> -    T0 = (int64_t)T0 >> PARAM1;
> -    if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
> -        env->xer |= (1 << XER_CA);
> -    } else {
> -        env->xer &= ~(1 << XER_CA);
> -    }
> -    RETURN();
> -}
> -#endif
> -
>  /* shift right word */
> -void OPPROTO op_srw (void)
> -{
> -    if (T1 & 0x20) {
> -        T0 = 0;
> -    } else {
> -        T0 = (uint32_t)T0 >> T1;
> -    }
> -    RETURN();
> -}
> -
> -#if defined(TARGET_PPC64)
> -void OPPROTO op_srd (void)
> -{
> -    if (T1 & 0x40) {
> -        T0 = 0;
> -    } else {
> -        T0 = (uint64_t)T0 >> T1;
> -    }
> -    RETURN();
> -}
> -#endif
> -
> -void OPPROTO op_sl_T0_T1 (void)
> -{
> -    T0 = T0 << T1;
> -    RETURN();
> -}
> -
>  void OPPROTO op_sli_T0 (void)
>  {
>     T0 = T0 << PARAM1;
>     RETURN();
>  }
>
> -void OPPROTO op_srl_T0_T1 (void)
> -{
> -    T0 = (uint32_t)T0 >> T1;
> -    RETURN();
> -}
> -
> -#if defined(TARGET_PPC64)
> -void OPPROTO op_srl_T0_T1_64 (void)
> -{
> -    T0 = (uint32_t)T0 >> T1;
> -    RETURN();
> -}
> -#endif
> -
>  void OPPROTO op_srli_T0 (void)
>  {
>     T0 = (uint32_t)T0 >> PARAM1;
> @@ -1215,14 +975,6 @@
>     RETURN();
>  }
>
> -#if defined(TARGET_PPC64)
> -void OPPROTO op_srli_T1_64 (void)
> -{
> -    T1 = (uint64_t)T1 >> PARAM1;
> -    RETURN();
> -}
> -#endif
> -
>  /***                       Floating-Point arithmetic                       
> ***/
>  /* fadd - fadd. */
>  void OPPROTO op_fadd (void)
>
> Modified: trunk/target-ppc/op_helper.c
> ===================================================================
> --- trunk/target-ppc/op_helper.c        2008-10-21 11:31:14 UTC (rev 5505)
> +++ trunk/target-ppc/op_helper.c        2008-10-21 11:31:27 UTC (rev 5506)
> @@ -368,96 +368,98 @@
>  }
>  #endif
>
> -void do_cntlzw (void)
> +target_ulong helper_cntlzw (target_ulong t)
>  {
> -    T0 = clz32(T0);
> +    return clz32(t);
>  }
>
>  #if defined(TARGET_PPC64)
> -void do_cntlzd (void)
> +target_ulong helper_cntlzd (target_ulong t)
>  {
> -    T0 = clz64(T0);
> +    return clz64(t);
>  }
>  #endif
>
>  /* shift right arithmetic helper */
> -void do_sraw (void)
> +target_ulong helper_sraw (target_ulong value, target_ulong shift)
>  {
>     int32_t ret;
>
> -    if (likely(!(T1 & 0x20UL))) {
> -        if (likely((uint32_t)T1 != 0)) {
> -            ret = (int32_t)T0 >> (T1 & 0x1fUL);
> -            if (likely(ret >= 0 || ((int32_t)T0 & ((1 << T1) - 1)) == 0)) {
> +    if (likely(!(shift & 0x20))) {
> +        if (likely((uint32_t)shift != 0)) {
> +            shift &= 0x1f;
> +            ret = (int32_t)value >> shift;
> +            if (likely(ret >= 0 || (value & ((1 << shift) - 1)) == 0)) {
>                 env->xer &= ~(1 << XER_CA);
>             } else {
>                 env->xer |= (1 << XER_CA);
>             }
>         } else {
> -            ret = T0;
> +            ret = (int32_t)value;
>             env->xer &= ~(1 << XER_CA);
>         }
>     } else {
> -        ret = UINT32_MAX * ((uint32_t)T0 >> 31);
> -        if (likely(ret >= 0 || ((uint32_t)T0 & ~0x80000000UL) == 0)) {
> +        ret = (int32_t)value >> 31;
> +        if (ret) {
> +            env->xer |= (1 << XER_CA);
> +        } else {
>             env->xer &= ~(1 << XER_CA);
> -        } else {
> -            env->xer |= (1 << XER_CA);
>         }
>     }
> -    T0 = ret;
> +    return (target_long)ret;
>  }
>
>  #if defined(TARGET_PPC64)
> -void do_srad (void)
> +target_ulong helper_srad (target_ulong value, target_ulong shift)
>  {
>     int64_t ret;
>
> -    if (likely(!(T1 & 0x40UL))) {
> -        if (likely((uint64_t)T1 != 0)) {
> -            ret = (int64_t)T0 >> (T1 & 0x3FUL);
> -            if (likely(ret >= 0 || ((int64_t)T0 & ((1 << T1) - 1)) == 0)) {
> +    if (likely(!(shift & 0x40))) {
> +        if (likely((uint64_t)shift != 0)) {
> +            shift &= 0x3f;
> +            ret = (int64_t)value >> shift;
> +            if (likely(ret >= 0 || (value & ((1 << shift) - 1)) == 0)) {
>                 env->xer &= ~(1 << XER_CA);
>             } else {
>                 env->xer |= (1 << XER_CA);
>             }
>         } else {
> -            ret = T0;
> +            ret = (int64_t)value;
>             env->xer &= ~(1 << XER_CA);
>         }
>     } else {
> -        ret = UINT64_MAX * ((uint64_t)T0 >> 63);
> -        if (likely(ret >= 0 || ((uint64_t)T0 & ~0x8000000000000000ULL) == 
> 0)) {
> +        ret = (int64_t)value >> 63;
> +        if (ret) {
> +            env->xer |= (1 << XER_CA);
> +        } else {
>             env->xer &= ~(1 << XER_CA);
> -        } else {
> -            env->xer |= (1 << XER_CA);
>         }
>     }
> -    T0 = ret;
> +    return ret;
>  }
>  #endif
>
> -void do_popcntb (void)
> +target_ulong helper_popcntb (target_ulong val)
>  {
>     uint32_t ret;
>     int i;
>
>     ret = 0;
>     for (i = 0; i < 32; i += 8)
> -        ret |= ctpop8((T0 >> i) & 0xFF) << i;
> -    T0 = ret;
> +        ret |= ctpop8((val >> i) & 0xFF) << i;
> +    return ret;
>  }
>
>  #if defined(TARGET_PPC64)
> -void do_popcntb_64 (void)
> +target_ulong helper_popcntb_64 (target_ulong val)
>  {
>     uint64_t ret;
>     int i;
>
>     ret = 0;
>     for (i = 0; i < 64; i += 8)
> -        ret |= ctpop8((T0 >> i) & 0xFF) << i;
> -    T0 = ret;
> +        ret |= ctpop8((val >> i) & 0xFF) << i;
> +    return ret;

Just noting, before I forget how ctpopXX() works, that the 8
iterations here can be replaced with one ctpop64 if you take only the
first 3 lines of it, i.e.

    val = (val & 0x5555555555555555ULL) + ((val >>  1) & 0x5555555555555555ULL);
    val = (val & 0x3333333333333333ULL) + ((val >>  2) & 0x3333333333333333ULL);
    val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >>  4) & 0x0f0f0f0f0f0f0f0fULL);

stores the ctpop8() value for each byte in the same byte.  Similarly
the 4 iterations above and ctpop32().




reply via email to

[Prev in Thread] Current Thread [Next in Thread]