mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 20:05:41 +00:00
* __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 svn path=/trunk/; revision=25619
This commit is contained in:
parent
2bf5cb7c4f
commit
d9a9b8a705
1 changed files with 23 additions and 68 deletions
|
@ -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 @@ static __inline__ __attribute__((always_inline)) unsigned short _rotr16(const un
|
|||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned long long __ll_lshift(const unsigned long long Mask, int Bit)
|
||||
/*
|
||||
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 lo32 = (unsigned long)((Mask >> 0) & 0xFFFFFFFF);
|
||||
unsigned long hi32 = (unsigned long)((Mask >> 32) & 0xFFFFFFFF);
|
||||
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)
|
||||
"shldl %b[Bit], %%eax, %%edx; sall %b[Bit], %%eax" :
|
||||
"+A" (retval) :
|
||||
[Bit] "Nc" ((unsigned char)((unsigned long)Bit) & 0xFF)
|
||||
);
|
||||
|
||||
{
|
||||
union u_
|
||||
{
|
||||
unsigned long long ull;
|
||||
struct s_
|
||||
{
|
||||
unsigned long lo32;
|
||||
unsigned long hi32;
|
||||
}
|
||||
s;
|
||||
}
|
||||
u = { s : { lo32 : lo32, hi32 : hi32 } };
|
||||
|
||||
return u.ull;
|
||||
}
|
||||
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)
|
||||
"shldl %b[Bit], %%eax, %%edx; sarl %b[Bit], %%eax" :
|
||||
"+A" (retval) :
|
||||
[Bit] "Nc" ((unsigned char)((unsigned long)Bit) & 0xFF)
|
||||
);
|
||||
|
||||
{
|
||||
union u_
|
||||
{
|
||||
long long ll;
|
||||
struct s_
|
||||
{
|
||||
unsigned long lo32;
|
||||
long hi32;
|
||||
}
|
||||
s;
|
||||
}
|
||||
u = { s : { lo32 : lo32, hi32 : hi32 } };
|
||||
|
||||
return u.ll;
|
||||
}
|
||||
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)
|
||||
"shrdl %b[Bit], %%eax, %%edx; shrl %b[Bit], %%eax" :
|
||||
"+A" (retval) :
|
||||
[Bit] "Nc" ((unsigned char)((unsigned long)Bit) & 0xFF)
|
||||
);
|
||||
|
||||
{
|
||||
union u_
|
||||
{
|
||||
unsigned long long ull;
|
||||
struct s_
|
||||
{
|
||||
unsigned long lo32;
|
||||
unsigned long hi32;
|
||||
}
|
||||
s;
|
||||
}
|
||||
u = { s : { lo32 : lo32, hi32 : hi32 } };
|
||||
|
||||
return u.ull;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue