From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KvNw3-0006WL-BB for qemu-devel@nongnu.org; Wed, 29 Oct 2008 23:10:59 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KvNw0-0006W9-Uh for qemu-devel@nongnu.org; Wed, 29 Oct 2008 23:10:58 -0400 Received: from [199.232.76.173] (port=36122 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KvNw0-0006W6-RE for qemu-devel@nongnu.org; Wed, 29 Oct 2008 23:10:56 -0400 Received: from rv-out-0708.google.com ([209.85.198.246]:50466) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1KvNw0-0002ts-H0 for qemu-devel@nongnu.org; Wed, 29 Oct 2008 23:10:56 -0400 Received: by rv-out-0708.google.com with SMTP id f25so325182rvb.22 for ; Wed, 29 Oct 2008 20:10:55 -0700 (PDT) Message-ID: Date: Thu, 30 Oct 2008 04:10:55 +0100 From: "andrzej zaborowski" Subject: Re: [Qemu-devel] [5506] target-ppc: convert logical instructions to TCG In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Content-Disposition: inline References: Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Hi, 2008/10/21 Aurelien Jarno : > 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 > > 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().