mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 22:52:58 +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
|
implementation - e.g. __stosX; on the other hand, some memory barriers that
|
||||||
*are* present could have been missed
|
*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
|
NOTE: this is a *compatibility* header. Some functions may look wrong at
|
||||||
|
@ -72,10 +69,6 @@
|
||||||
would use in the same case
|
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__
|
#ifdef __i386__
|
||||||
|
|
||||||
/*** Stack frame juggling ***/
|
/*** Stack frame juggling ***/
|
||||||
|
@ -685,91 +678,53 @@ static __inline__ __attribute__((always_inline)) unsigned short _rotr16(const un
|
||||||
return retval;
|
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 long retval = Mask;
|
||||||
unsigned long hi32 = (unsigned long)((Mask >> 32) & 0xFFFFFFFF);
|
|
||||||
|
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"shldl %b[Bit], %k[Lo32], %k[Hi32]; sall %b[Bit], %k[Lo32]" :
|
"shldl %b[Bit], %%eax, %%edx; sall %b[Bit], %%eax" :
|
||||||
[Lo32] "=q" (lo32), [Hi32] "=qm" (hi32):
|
"+A" (retval) :
|
||||||
"[Lo32]" (lo32), "[Hi32]" (hi32), [Bit] "Ic" (Bit)
|
[Bit] "Nc" ((unsigned char)((unsigned long)Bit) & 0xFF)
|
||||||
);
|
);
|
||||||
|
|
||||||
{
|
return retval;
|
||||||
union u_
|
|
||||||
{
|
|
||||||
unsigned long long ull;
|
|
||||||
struct s_
|
|
||||||
{
|
|
||||||
unsigned long lo32;
|
|
||||||
unsigned long hi32;
|
|
||||||
}
|
|
||||||
s;
|
|
||||||
}
|
|
||||||
u = { s : { lo32 : lo32, hi32 : hi32 } };
|
|
||||||
|
|
||||||
return u.ull;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ __attribute__((always_inline)) long long __ll_rshift(const long long Mask, const int Bit)
|
static __inline__ __attribute__((always_inline)) long long __ll_rshift(const long long Mask, const int Bit)
|
||||||
{
|
{
|
||||||
unsigned long lo32 = (unsigned long)((Mask >> 0) & 0xFFFFFFFF);
|
unsigned long long retval = Mask;
|
||||||
long hi32 = (unsigned long)((Mask >> 32) & 0xFFFFFFFF);
|
|
||||||
|
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"shrdl %b[Bit], %k[Lo32], %k[Hi32]; sarl %b[Bit], %k[Lo32]" :
|
"shldl %b[Bit], %%eax, %%edx; sarl %b[Bit], %%eax" :
|
||||||
[Lo32] "=q" (lo32), [Hi32] "=qm" (hi32):
|
"+A" (retval) :
|
||||||
"[Lo32]" (lo32), "[Hi32]" (hi32), [Bit] "Ic" (Bit)
|
[Bit] "Nc" ((unsigned char)((unsigned long)Bit) & 0xFF)
|
||||||
);
|
);
|
||||||
|
|
||||||
{
|
return retval;
|
||||||
union u_
|
|
||||||
{
|
|
||||||
long long ll;
|
|
||||||
struct s_
|
|
||||||
{
|
|
||||||
unsigned long lo32;
|
|
||||||
long hi32;
|
|
||||||
}
|
|
||||||
s;
|
|
||||||
}
|
|
||||||
u = { s : { lo32 : lo32, hi32 : hi32 } };
|
|
||||||
|
|
||||||
return u.ll;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ __attribute__((always_inline)) unsigned long long __ull_rshift(const unsigned long long Mask, int Bit)
|
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 long retval = Mask;
|
||||||
unsigned long hi32 = (unsigned long)((Mask >> 32) & 0xFFFFFFFF);
|
|
||||||
|
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"shrdl %b[Bit], %k[Hi32], %k[Lo32]; shrl %b[Bit], %k[Hi32]" :
|
"shrdl %b[Bit], %%eax, %%edx; shrl %b[Bit], %%eax" :
|
||||||
[Lo32] "=qm" (lo32), [Hi32] "=q" (hi32):
|
"+A" (retval) :
|
||||||
"[Lo32]" (lo32), "[Hi32]" (hi32), [Bit] "Ic" (Bit)
|
[Bit] "Nc" ((unsigned char)((unsigned long)Bit) & 0xFF)
|
||||||
);
|
);
|
||||||
|
|
||||||
{
|
return retval;
|
||||||
union u_
|
|
||||||
{
|
|
||||||
unsigned long long ull;
|
|
||||||
struct s_
|
|
||||||
{
|
|
||||||
unsigned long lo32;
|
|
||||||
unsigned long hi32;
|
|
||||||
}
|
|
||||||
s;
|
|
||||||
}
|
|
||||||
u = { s : { lo32 : lo32, hi32 : hi32 } };
|
|
||||||
|
|
||||||
return u.ull;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue