[ros-diffs] [hyperion] 25619: * __ll_lshift, __ll_rshift, __ull_rshift: fixed handling of 64-bit arguments and return values by forcing them to be passed as EDX:EAX. Finally generates decent code * updated comments to reflect current state of the code

hyperion at svn.reactos.org hyperion at svn.reactos.org
Wed Jan 24 19:01:35 CET 2007


Author: hyperion
Date: Wed Jan 24 21:01:34 2007
New Revision: 25619

URL: http://svn.reactos.org/svn/reactos?rev=25619&view=rev
Log:
 * __ll_lshift, __ll_rshift, __ull_rshift: fixed handling of 64-bit arguments and return values by forcing them to be passed as EDX:EAX. Finally generates decent code
 * updated comments to reflect current state of the code

Modified:
    trunk/reactos/include/psdk/intrin.h

Modified: trunk/reactos/include/psdk/intrin.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/psdk/intrin.h?rev=25619&r1=25618&r2=25619&view=diff
==============================================================================
--- trunk/reactos/include/psdk/intrin.h (original)
+++ trunk/reactos/include/psdk/intrin.h Wed Jan 24 21:01:34 2007
@@ -38,9 +38,6 @@
 	implementation - e.g. __stosX; on the other hand, some memory barriers that
 	*are* present could have been missed
 */
-/*
-	FIXME: atomic intrinsics haven't been tested yet
-*/
 
 /*
 	NOTE: this is a *compatibility* header. Some functions may look wrong at
@@ -72,10 +69,6 @@
 	would use in the same case
 */
 
-/*
-	BUGBUG: 'long long' arguments and returns mess up GCC royally. There has to
-	be something we can do about them
-*/
 #ifdef __i386__
 
 /*** Stack frame juggling ***/
@@ -685,91 +678,53 @@
 	return retval;
 }
 
-static __inline__ __attribute__((always_inline)) unsigned long long __ll_lshift(const unsigned long long Mask, int Bit)
-{
-	unsigned long lo32 = (unsigned long)((Mask >>  0) & 0xFFFFFFFF);
-	unsigned long hi32 = (unsigned long)((Mask >> 32) & 0xFFFFFFFF);
+/*
+	NOTE: in __ll_lshift, __ll_rshift and __ull_rshift we use the "A"
+	constraint (edx:eax) for the Mask argument, because it's the only way GCC
+	can pass 64-bit operands around - passing the two 32 bit parts separately
+	just confuses it. Also we declare Bit as an int and then truncate it to
+	match Visual C++ behavior
+*/
+static __inline__ __attribute__((always_inline)) unsigned long long __ll_lshift(const unsigned long long Mask, const int Bit)
+{
+	unsigned long long retval = Mask;
 
 	__asm__
 	(
-		"shldl %b[Bit], %k[Lo32], %k[Hi32]; sall %b[Bit], %k[Lo32]" :
-		[Lo32] "=q" (lo32), [Hi32] "=qm" (hi32):
-		"[Lo32]" (lo32), "[Hi32]" (hi32), [Bit] "Ic" (Bit)
-	);
-
-	{
-		union u_
-		{
-			unsigned long long ull;
-			struct s_
-			{
-				unsigned long lo32;
-				unsigned long hi32;
-			}
-			s;
-		}
-		u = { s : { lo32 : lo32, hi32 : hi32 } };
-
-		return u.ull;
-	}
+		"shldl %b[Bit], %%eax, %%edx; sall %b[Bit], %%eax" :
+		"+A" (retval) :
+		[Bit] "Nc" ((unsigned char)((unsigned long)Bit) & 0xFF)
+	);
+
+	return retval;
 }
 
 static __inline__ __attribute__((always_inline)) long long __ll_rshift(const long long Mask, const int Bit)
 {
-	unsigned long lo32 = (unsigned long)((Mask >>  0) & 0xFFFFFFFF);
-	long hi32 = (unsigned long)((Mask >> 32) & 0xFFFFFFFF);
+	unsigned long long retval = Mask;
 
 	__asm__
 	(
-		"shrdl %b[Bit], %k[Lo32], %k[Hi32]; sarl %b[Bit], %k[Lo32]" :
-		[Lo32] "=q" (lo32), [Hi32] "=qm" (hi32):
-		"[Lo32]" (lo32), "[Hi32]" (hi32), [Bit] "Ic" (Bit)
-	);
-
-	{
-		union u_
-		{
-			long long ll;
-			struct s_
-			{
-				unsigned long lo32;
-				long hi32;
-			}
-			s;
-		}
-		u = { s : { lo32 : lo32, hi32 : hi32 } };
-
-		return u.ll;
-	}
+		"shldl %b[Bit], %%eax, %%edx; sarl %b[Bit], %%eax" :
+		"+A" (retval) :
+		[Bit] "Nc" ((unsigned char)((unsigned long)Bit) & 0xFF)
+	);
+
+	return retval;
 }
 
 static __inline__ __attribute__((always_inline)) unsigned long long __ull_rshift(const unsigned long long Mask, int Bit)
 {
-	unsigned long lo32 = (unsigned long)((Mask >>  0) & 0xFFFFFFFF);
-	unsigned long hi32 = (unsigned long)((Mask >> 32) & 0xFFFFFFFF);
+	unsigned long long retval = Mask;
 
 	__asm__
 	(
-		"shrdl %b[Bit], %k[Hi32], %k[Lo32]; shrl %b[Bit], %k[Hi32]" :
-		[Lo32] "=qm" (lo32), [Hi32] "=q" (hi32):
-		"[Lo32]" (lo32), "[Hi32]" (hi32), [Bit] "Ic" (Bit)
-	);
-
-	{
-		union u_
-		{
-			unsigned long long ull;
-			struct s_
-			{
-				unsigned long lo32;
-				unsigned long hi32;
-			}
-			s;
-		}
-		u = { s : { lo32 : lo32, hi32 : hi32 } };
-
-		return u.ull;
-	}
+		"shrdl %b[Bit], %%eax, %%edx; shrl %b[Bit], %%eax" :
+		"+A" (retval) :
+		[Bit] "Nc" ((unsigned char)((unsigned long)Bit) & 0xFF)
+	);
+
+	return retval;
 }
 
 




More information about the Ros-diffs mailing list