From rgammon at real.com Thu Jan 20 12:34:41 2005
From: rgammon at real.com (Ryan Gammon)
Date: Thu Jan 20 12:41:02 2005
Subject: [Porting-amd64] Re: [Common-dev] MulShift32 on linux/x86-64
In-Reply-To: <41F014D9.9030300@real.com>
References: <1106244297.12497.18.camel@localhost.localdomain>
<41F007A8.9020906@real.com> <41F00C50.1070101@real.com>
<41F0145A.8070107@real.com> <41F014D9.9030300@real.com>
Message-ID: <41F015E1.500@real.com>
Actually, http://crashrecovery.org/helixp/ is Robert M. Stockmann's
Ryan Gammon wrote:
> From helix-amd64-platform.patch.bz2:
>
> /***********************************************************************
> + * Intel x86/amd64/x86_64 (gcc) / Unix -- 64-bit
> + *
> + * Implementation Notes:
> + *
> + */
> +#elif defined(__GNUC__) && (defined (__amd64__) || defined (__x86_64__))
> +
> +/* Increment by 1 */
> +static __inline__ void
> +HXAtomicIncUINT32(UINT32* pNum)
> +{
> + __asm__ __volatile__(
> + "lock incl (%%rax);" // atomically add 1 to *pNum
> + : /* no output */
> + : "a" (pNum)
> + : "cc", "memory"
> + );
> +}
> +
> +/* Decrement by 1 */
> +static __inline__ void
> +HXAtomicDecUINT32(UINT32* pNum)
> +{
> + __asm__ __volatile__(
> + "lock decl (%%rax);" // atomically add -1 to *pNum
> + : /* no output */
> + : "a" (pNum)
> + : "cc", "memory"
> + );
> +}
> +
> +/* Increment by 1 and return new value */
> +static __inline__ UINT32
> +HXAtomicIncRetUINT32(UINT32* pNum)
> +{
> + volatile UINT32 ulRet;
> + __asm__ __volatile__(
> + "lock xaddl %%ebx, (%%rax);" // atomically add 1 to *pNum
> + " incl %%ebx;" // old value in %%ebx,
> increment it
> + : "=b" (ulRet)
> + : "a" (pNum), "b" (0x1)
> + : "cc", "memory"
> + );
> + return ulRet;
> +}
> +
> +/* Decrement by 1 and return new value */
> +static __inline__ UINT32
> +HXAtomicDecRetUINT32(UINT32* pNum)
> +{ + volatile UINT32 ulRet;
> + __asm__ __volatile__(
> + "lock xaddl %%ebx, (%%rax);" // atomically add -1 to *pNum
> + " decl %%ebx;" // old value in %%ebx,
> decrement it
> + : "=b" (ulRet)
> + : "a" (pNum), "b" (-1)
> + : "cc", "memory"
> + );
> + return ulRet;
> +}
> +
> +/* Add n */
> +static __inline__ void
> +HXAtomicAddUINT32(UINT32* pNum, UINT32 ulNum)
> +{
> + __asm__ __volatile__(
> + "lock addl %%ebx, (%%rax);" // atomically add ulNum to
> *pNum
> + : /* no output */
> + : "a" (pNum), "b" (ulNum)
> + : "cc", "memory"
> + );
> +}
> +
> +/* Subtract n */
> +static __inline__ void
> +HXAtomicSubUINT32(UINT32* pNum, UINT32 ulNum)
> +{
> + __asm__ __volatile__(
> + "lock subl %%ebx, (%%rax);" // atomically add ulNum to
> *pNum
> + : /* no output */
> + : "a" (pNum), "b" (ulNum)
> + : "cc", "memory"
> + );
> +}
> +
> +/* Add n and return new value */
> +static __inline__ UINT32
> +HXAtomicAddRetUINT32(UINT32* pNum, UINT32 ulNum)
> +{
> + volatile UINT32 ulRet;
> + __asm__ __volatile__(
> + " movl %%ebx, %%ecx;" // copy ulNum into %0
> + "lock xaddl %%ecx, (%%rax);" // atomically add ulNum to
> *pNum
> + " addl %%ebx, %%ecx;" // old value in %%ecx, add
> ulNum
> + : "=c" (ulRet)
> + : "a" (pNum), "b" (ulNum), "c" (0)
> + : "cc", "memory"
> + );
> + return ulRet;
> +}
> +
> +/* Subtract n and return new value */
> +static __inline__ UINT32
> +HXAtomicSubRetUINT32(UINT32* pNum, UINT32 ulNum)
> +{ + volatile UINT32 ulRet;
> + __asm__ __volatile__(
> + " subl %%ebx, %%ecx;" // negate ulNum, saving in %0
> + "lock xaddl %%ecx, (%%rax);" // atomically add -(ulNum)
> to *pNum
> + " subl %%ebx, %%ecx;" // old value in %%ecx,
> subtract ulNum
> + : "=c" (ulRet)
> + : "a" (pNum), "b" (ulNum), "c" (0)
> + : "cc", "memory"
> + );
> + return ulRet;
> +}
> +
> +
> +static __inline__ void HXAtomicIncINT32(INT32* p) {
> HXAtomicIncUINT32((UINT32*)p); }
> +static __inline__ void HXAtomicDecINT32(INT32* p) {
> HXAtomicDecUINT32((UINT32*)p); }
> +static __inline__ void HXAtomicAddINT32(INT32* p, INT32 n) {
> HXAtomicAddUINT32((UINT32*)p, (UINT32)n); }
> +static __inline__ void HXAtomicSubINT32(INT32* p, INT32 n) {
> HXAtomicSubUINT32((UINT32*)p, (UINT32)n); }
> +static __inline__ INT32 HXAtomicIncRetINT32(INT32* p) {
> return HXAtomicIncRetUINT32((UINT32*)p); }
> +static __inline__ INT32 HXAtomicDecRetINT32(INT32* p) {
> return HXAtomicDecRetUINT32((UINT32*)p); }
> +static __inline__ INT32 HXAtomicAddRetINT32(INT32* p, INT32 n) {
> return HXAtomicAddRetUINT32((UINT32*)p, (UINT32)n); }
> +static __inline__ INT32 HXAtomicSubRetINT32(INT32* p, INT32 n) {
> return HXAtomicSubRetUINT32((UINT32*)p, (UINT32)n); }
> +
> +
> +
> +/***********************************************************************
>
>
> Greg Wright wrote:
>
>> Yup, the i386 ones were used:
>>
>> @@ -124,7 +124,7 @@
>> // GCC / i386
>> ///////////////////////////////////////////////////////////////////////////////////////
>>
>>
>> -#if defined(__GNUC__) && defined(__i386__) && !defined(_NO_GNU_AS)
>> +#if defined(__GNUC__) && defined(__i386__) || defined(__amd64__) &&
>> !defined(_NO_GNU_AS)
>>
>> #define HAVE_PLATFORM_MACROS
>>
>>
>> --greg.
>>
>>
>>
>> Ryan Gammon wrote:
>>
>>> Jose Alberto Reguero submitted some patches on porting-amd64 which
>>> included some of this stuff. His latest is at:
>>>
>>> http://crashrecovery.org/helixp/
>>>
>>>
>>> Greg Wright wrote:
>>>
>>>> My guess would be that 64-bit x86 is backwards compatible with
>>>> the i386 instructions. There is a test in fixptutils/test
>>>> that you could compile and run real fast.
>>>>
>>>> It might be fun to just write a very tiny main.cpp that included
>>>> math64.h (using c versions of all routines) and just call MulShift32.
>>>> Then just look at the assembly it generates and see if it is
>>>> using the i386 instructions. You could even grab the assembly,
>>>> hand tune it and use that for the math64.h inlines if you wanted.
>>>>
>>>> However, someone who has done some 64-bit work might just know
>>>> that answer.
>>>>
>>>> --greg.
>>>>
>>>>
>>>> Nicholas Hart wrote:
>>>>
>>>>> Is there an implementation for MulShift32 (and the other
>>>>> audio/fixptutil/pub/math64.h functions) for linux/x86-64?
>>>>>
>>>>> I'm trying to build the client engine and it's failing in
>>>>> client/audiodev because this function is missing. Honestly I
>>>>> don't know
>>>>> enough about i386 vs x86-64 to know if we can re-use the i386
>>>>> implementation or not.
>>>>>
>>>>>
>>>>
>>>> _______________________________________________
>>>> Common-dev mailing list
>>>> Common-dev@helixcommunity.org
>>>> http://lists.helixcommunity.org/mailman/listinfo/common-dev
>>>>
>>>
>>>
>>
>
>
--
Ryan Gammon
rgammon@real.com
Developer for Helix Player
https://player.helixcommunity.org
Copyright © 1995-2007 RealNetworks, Inc. All rights reserved.
RealNetworks and Helix are trademarks of RealNetworks.
All other trademarks or registered trademarks are the property of their respective holders.