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


 

Site Map   |   Terms of Use   |   Privacy Policy   |   Contact Us

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.