blob: d6086fbce89977a628a6a9fab38ce6efbe76eff3 [file] [log] [blame]
/*
* Large integer functions
*
* Copyright 2000 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "winnt.h"
#include "ntddk.h"
/*
* Note: we use LONGLONG instead of LARGE_INTEGER, because
* the latter is a structure and the calling convention for
* returning a structure would not be binary-compatible.
*
* FIXME: for platforms that don't have a native LONGLONG type,
* we should define LONGLONG as a structure similar to LARGE_INTEGER
* and do everything by hand. You are welcome to do it...
*/
/******************************************************************************
* RtlLargeIntegerAdd (NTDLL.@)
*/
LONGLONG WINAPI RtlLargeIntegerAdd( LONGLONG a, LONGLONG b )
{
return a + b;
}
/******************************************************************************
* RtlLargeIntegerSubtract (NTDLL.@)
*/
LONGLONG WINAPI RtlLargeIntegerSubtract( LONGLONG a, LONGLONG b )
{
return a - b;
}
/******************************************************************************
* RtlLargeIntegerNegate (NTDLL.@)
*/
LONGLONG WINAPI RtlLargeIntegerNegate( LONGLONG a )
{
return -a;
}
/******************************************************************************
* RtlLargeIntegerShiftLeft (NTDLL.@)
*/
LONGLONG WINAPI RtlLargeIntegerShiftLeft( LONGLONG a, INT count )
{
return a << count;
}
/******************************************************************************
* RtlLargeIntegerShiftRight (NTDLL.@)
*/
LONGLONG WINAPI RtlLargeIntegerShiftRight( LONGLONG a, INT count )
{
return (ULONGLONG)a >> count;
}
/******************************************************************************
* RtlLargeIntegerArithmeticShift (NTDLL.@)
*/
LONGLONG WINAPI RtlLargeIntegerArithmeticShift( LONGLONG a, INT count )
{
/* FIXME: gcc does arithmetic shift here, but it may not be true on all platforms */
return a >> count;
}
/******************************************************************************
* RtlLargeIntegerDivide (NTDLL.@)
*
* FIXME: should it be signed division instead?
*/
ULONGLONG WINAPI RtlLargeIntegerDivide( ULONGLONG a, ULONGLONG b, ULONGLONG *rem )
{
ULONGLONG ret = a / b;
if (rem) *rem = a - ret * b;
return ret;
}
/******************************************************************************
* RtlConvertLongToLargeInteger (NTDLL.@)
*/
LONGLONG WINAPI RtlConvertLongToLargeInteger( LONG a )
{
return a;
}
/******************************************************************************
* RtlConvertUlongToLargeInteger (NTDLL.@)
*/
ULONGLONG WINAPI RtlConvertUlongToLargeInteger( ULONG a )
{
return a;
}
/******************************************************************************
* RtlEnlargedIntegerMultiply (NTDLL.@)
*/
LONGLONG WINAPI RtlEnlargedIntegerMultiply( INT a, INT b )
{
return (LONGLONG)a * b;
}
/******************************************************************************
* RtlEnlargedUnsignedMultiply (NTDLL.@)
*/
ULONGLONG WINAPI RtlEnlargedUnsignedMultiply( UINT a, UINT b )
{
return (ULONGLONG)a * b;
}
/******************************************************************************
* RtlEnlargedUnsignedDivide (NTDLL.@)
*/
UINT WINAPI RtlEnlargedUnsignedDivide( ULONGLONG a, UINT b, UINT *remptr )
{
#if defined(__i386__) && defined(__GNUC__)
UINT ret, rem;
__asm__("div %4,%%eax"
: "=a" (ret), "=d" (rem)
: "0" (*(UINT*)&a), "1" (*((UINT*)&a+1)), "g" (b) );
if (remptr) *remptr = rem;
return ret;
#else
UINT ret = a / b;
if (remptr) *remptr = a % b;
return ret;
#endif
}
/******************************************************************************
* RtlExtendedLargeIntegerDivide (NTDLL.@)
*/
LONGLONG WINAPI RtlExtendedLargeIntegerDivide( LONGLONG a, INT b, INT *rem )
{
LONGLONG ret = a / b;
if (rem) *rem = a - b * ret;
return ret;
}
/******************************************************************************
* RtlExtendedIntegerMultiply (NTDLL.@)
*/
LONGLONG WINAPI RtlExtendedIntegerMultiply( LONGLONG a, INT b )
{
return a * b;
}
/******************************************************************************
* RtlExtendedMagicDivide (NTDLL.@)
*
* This function computes (a * b) >> (64 + shift)
*
* This allows replacing a division by a longlong constant
* by a multiplication by the inverse constant.
*
* If 'c' is the constant divisor, the constants 'b' and 'shift'
* must be chosen such that b = 2^(64+shift) / c.
* Then we have RtlExtendedMagicDivide(a,b,shift) == a * b / 2^(64+shift) == a / c.
*
* I'm too lazy to implement it right now...
*/
/* LONGLONG WINAPI RtlExtendedMagicDivide( LONGLONG a, LONGLONG b, INT shift )
* {
* return 0;
* }
*/
/******************************************************************************
* _alldiv (NTDLL.@)
*/
LONGLONG WINAPI _alldiv( LONGLONG a, LONGLONG b )
{
return a / b;
}
/******************************************************************************
* _allmul (NTDLL.@)
*/
LONGLONG WINAPI _allmul( LONGLONG a, LONGLONG b )
{
return a * b;
}
/******************************************************************************
* _allrem (NTDLL.@)
*/
LONGLONG WINAPI _allrem( LONGLONG a, LONGLONG b )
{
return a % b;
}
/******************************************************************************
* _aulldiv (NTDLL.@)
*/
ULONGLONG WINAPI _aulldiv( ULONGLONG a, ULONGLONG b )
{
return a / b;
}
/******************************************************************************
* _aullrem (NTDLL.@)
*/
ULONGLONG WINAPI _aullrem( ULONGLONG a, ULONGLONG b )
{
return a % b;
}