uint128.h revision c1d279fc0865b91a40b30eda02ed14f6533fe1a4
/** @file
* IPRT - RTUINT128U & uint128_t methods.
*/
/*
* Copyright (C) 2011-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*/
#ifndef ___iprt_uint128_h
#define ___iprt_uint128_h
#ifdef RT_ARCH_AMD64
# include <iprt/asm-math.h>
#endif
/** @defgroup grp_rt_uint128 RTUInt128 - 128-bit Unsigned Integer Methods
* @ingroup grp_rt
* @{
*/
/**
* Test if a 128-bit unsigned integer value is zero.
*
* @returns true if they are, false if they aren't.
* @param pValue The input and output value.
*/
{
#if ARCH_BITS >= 64
#else
#endif
}
/**
* Set a 128-bit unsigned integer value to zero.
*
* @returns pResult
* @param pResult The result variable.
*/
{
#if ARCH_BITS >= 64
#else
#endif
return pResult;
}
/**
* Set a 128-bit unsigned integer value to the maximum value.
*
* @returns pResult
* @param pResult The result variable.
*/
{
#if ARCH_BITS >= 64
#else
#endif
return pResult;
}
/**
* Adds two 128-bit unsigned integer values.
*
* @returns pResult
* @param pResult The result variable.
* @param pValue1 The first value.
* @param pValue2 The second value.
*/
DECLINLINE(PRTUINT128U) RTUInt128Add(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2)
{
return pResult;
}
/**
* Adds a 128-bit and a 64-bit unsigned integer values.
*
* @returns pResult
* @param pResult The result variable.
* @param pValue1 The first value.
* @param uValue2 The second value, 64-bit.
*/
DECLINLINE(PRTUINT128U) RTUInt128AddU64(PRTUINT128U pResult, PCRTUINT128U pValue1, uint64_t uValue2)
{
return pResult;
}
/**
* Subtracts a 128-bit unsigned integer value from another.
*
* @returns pResult
* @param pResult The result variable.
* @param pValue1 The minuend value.
* @param pValue2 The subtrahend value.
*/
DECLINLINE(PRTUINT128U) RTUInt128Sub(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2)
{
return pResult;
}
/**
* Multiplies two 128-bit unsigned integer values.
*
* @returns pResult
* @param pResult The result variable.
* @param pValue1 The first value.
* @param pValue2 The second value.
*/
DECLINLINE(PRTUINT128U) RTUInt128Mul(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2)
{
/* multiply all dwords in v1 by v2.dw0. */
/* multiply dw0, dw1 & dw2 in v1 by v2.dw1. */
/* multiply dw0 & dw1 in v1 by v2.dw2. */
/* multiply dw0 in v1 by v2.dw3. */
return pResult;
}
/**
* Multiplies an 128-bit unsigned integer by a 64-bit unsigned integer value.
*
* @returns pResult
* @param pResult The result variable.
* @param pValue1 The first value.
* @param uValue2 The second value, 64-bit.
*/
#if defined(RT_ARCH_AMD64)
#else
DECLINLINE(PRTUINT128U) RTUInt128MulByU64(PRTUINT128U pResult, PCRTUINT128U pValue1, uint64_t uValue2)
{
/* multiply all dwords in v1 by uLoValue1. */
/* multiply dw0, dw1 & dw2 in v1 by uHiValue2. */
return pResult;
}
#endif
/**
* Multiplies two 64-bit unsigned integer values with 128-bit precision.
*
* @returns pResult
* @param pResult The result variable.
* @param uValue1 The first value. 64-bit.
* @param uValue2 The second value, 64-bit.
*/
DECLINLINE(PRTUINT128U) RTUInt128MulU64ByU64(PRTUINT128U pResult, uint64_t uValue1, uint64_t uValue2)
{
#ifdef RT_ARCH_AMD64
#else
/* Multiply uLoValue1 and uHiValue1 by uLoValue1. */
/* Multiply uLoValue1 and uHiValue1 by uHiValue2. */
#endif
return pResult;
}
DECLINLINE(PRTUINT128U) RTUInt128DivRem(PRTUINT128U pQuotient, PRTUINT128U pRemainder, PCRTUINT128U pValue1, PCRTUINT128U pValue2);
/**
* Divides a 128-bit unsigned integer value by another.
*
* @returns pResult
* @param pResult The result variable.
* @param pValue1 The dividend value.
* @param pValue2 The divisor value.
*/
DECLINLINE(PRTUINT128U) RTUInt128Div(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2)
{
}
/**
* Divides a 128-bit unsigned integer value by another, returning the remainder.
*
* @returns pResult
* @param pResult The result variable (remainder).
* @param pValue1 The dividend value.
* @param pValue2 The divisor value.
*/
DECLINLINE(PRTUINT128U) RTUInt128Mod(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2)
{
return pResult;
}
/**
* Bitwise AND of two 128-bit unsigned integer values.
*
* @returns pResult
* @param pResult The result variable.
* @param pValue1 The first value.
* @param pValue2 The second value.
*/
DECLINLINE(PRTUINT128U) RTUInt128And(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2)
{
return pResult;
}
/**
* Bitwise OR of two 128-bit unsigned integer values.
*
* @returns pResult
* @param pResult The result variable.
* @param pValue1 The first value.
* @param pValue2 The second value.
*/
DECLINLINE(PRTUINT128U) RTUInt128Or( PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2)
{
return pResult;
}
/**
* Bitwise XOR of two 128-bit unsigned integer values.
*
* @returns pResult
* @param pResult The result variable.
* @param pValue1 The first value.
* @param pValue2 The second value.
*/
DECLINLINE(PRTUINT128U) RTUInt128Xor(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2)
{
return pResult;
}
/**
* Shifts a 128-bit unsigned integer value @a cBits to the left.
*
* @returns pResult
* @param pResult The result variable.
* @param pValue The value to shift.
* @param cBits The number of bits to shift it.
*/
{
cBits &= 127;
if (cBits < 64)
{
}
else
{
}
return pResult;
}
/**
* Shifts a 128-bit unsigned integer value @a cBits to the right.
*
* @returns pResult
* @param pResult The result variable.
* @param pValue The value to shift.
* @param cBits The number of bits to shift it.
*/
{
cBits &= 127;
if (cBits < 64)
{
}
else
{
}
return pResult;
}
/**
* Boolean not (result 0 or 1).
*
* @returns pResult.
* @param pResult The result variable.
* @param pValue The value.
*/
{
return pResult;
}
/**
* Bitwise not (flips each bit of the 128 bits).
*
* @returns pResult.
* @param pResult The result variable.
* @param pValue The value.
*/
{
return pResult;
}
/**
* Assigns one 128-bit unsigned integer value to another.
*
* @returns pResult
* @param pResult The result variable.
* @param pValue The value to assign.
*/
{
#if ARCH_BITS >= 64
#else
#endif
return pResult;
}
/**
* Assigns a boolean value to 128-bit unsigned integer.
*
* @returns pResult
* @param pResult The result variable.
* @param fValue The boolean value.
*/
{
#if ARCH_BITS >= 64
pValueResult->s.Hi = 0;
#else
#endif
return pValueResult;
}
/**
* Assigns a 8-bit unsigned integer value to 128-bit unsigned integer.
*
* @returns pResult
* @param pResult The result variable.
* @param u8Value The 8-bit unsigned integer value.
*/
{
#if ARCH_BITS >= 64
pValueResult->s.Hi = 0;
#else
#endif
return pValueResult;
}
/**
* Assigns a 16-bit unsigned integer value to 128-bit unsigned integer.
*
* @returns pResult
* @param pResult The result variable.
* @param u16Value The 16-bit unsigned integer value.
*/
{
#if ARCH_BITS >= 64
pValueResult->s.Hi = 0;
#else
#endif
return pValueResult;
}
/**
* Assigns a 16-bit unsigned integer value to 128-bit unsigned integer.
*
* @returns pResult
* @param pResult The result variable.
* @param u32Value The 32-bit unsigned integer value.
*/
{
#if ARCH_BITS >= 64
pValueResult->s.Hi = 0;
#else
#endif
return pValueResult;
}
/**
* Assigns a 64-bit unsigned integer value to 128-bit unsigned integer.
*
* @returns pResult
* @param pResult The result variable.
* @param u32Value The 32-bit unsigned integer value.
*/
{
pValueResult->s.Hi = 0;
return pValueResult;
}
/**
* Adds two 128-bit unsigned integer values, storing the result in the first.
*
* @returns pValue1Result.
* @param pValue1Result The first value and result.
* @param pValue2 The second value.
*/
{
pValue1Result->s.Hi++;
return pValue1Result;
}
/**
* Adds a 64-bit unsigned integer value to a 128-bit unsigned integer values,
* storing the result in the 128-bit one.
*
* @returns pValue1Result.
* @param pValue1Result The first value and result.
* @param uValue2 The second value, 64-bit.
*/
{
pValue1Result->s.Hi++;
return pValue1Result;
}
/**
* Subtracts two 128-bit unsigned integer values, storing the result in the
* first.
*
* @returns pValue1Result.
* @param pValue1Result The minuend value and result.
* @param pValue2 The subtrahend value.
*/
{
pValue1Result->s.Hi--;
return pValue1Result;
}
/**
* Multiplies two 128-bit unsigned integer values, storing the result in the
* first.
*
* @returns pValue1Result.
* @param pValue1Result The first value and result.
* @param pValue2 The second value.
*/
{
*pValue1Result = Result;
return pValue1Result;
}
/**
* Divides a 128-bit unsigned integer value by another, storing the result in
* the first.
*
* @returns pValue1Result.
* @param pValue1Result The dividend value and result.
* @param pValue2 The divisor value.
*/
{
*pValue1Result = Result;
return pValue1Result;
}
/**
* Divides a 128-bit unsigned integer value by another, storing the remainder in
* the first.
*
* @returns pValue1Result.
* @param pValue1Result The dividend value and result (remainder).
* @param pValue2 The divisor value.
*/
{
*pValue1Result = Result;
return pValue1Result;
}
/**
* Performs a bitwise AND of two 128-bit unsigned integer values and assigned
* the result to the first one.
*
* @returns pValue1Result.
* @param pValue1Result The first value and result.
* @param pValue2 The second value.
*/
{
#if ARCH_BITS >= 64
#else
#endif
return pValue1Result;
}
/**
* Performs a bitwise AND of a 128-bit unsigned integer value and a mask made
* up of the first N bits, assigning the result to the the 128-bit value.
*
* @returns pValueResult.
* @param pValueResult The value and result.
* @param cBits The number of bits to AND (counting from the first
* bit).
*/
{
if (cBits <= 64)
{
if (cBits != 64)
pValueResult->s.Hi = 0;
}
else if (cBits < 128)
/** @todo #if ARCH_BITS >= 64 */
return pValueResult;
}
/**
* Performs a bitwise OR of two 128-bit unsigned integer values and assigned
* the result to the first one.
*
* @returns pValue1Result.
* @param pValue1Result The first value and result.
* @param pValue2 The second value.
*/
{
#if ARCH_BITS >= 64
#else
#endif
return pValue1Result;
}
/**
* ORs in a bit and assign the result to the input value.
*
* @returns pValue1Result.
* @param pValue1Result The first value and result.
* @param iBit The bit to set (0 based).
*/
{
#if ARCH_BITS >= 64
if (iBit >= 64)
else
#else
if (iBit >= 64)
{
if (iBit >= 96)
else
}
else
{
if (iBit >= 32)
else
}
#endif
return pValue1Result;
}
/**
* Performs a bitwise XOR of two 128-bit unsigned integer values and assigned
* the result to the first one.
*
* @returns pValue1Result.
* @param pValue1Result The first value and result.
* @param pValue2 The second value.
*/
{
#if ARCH_BITS >= 64
#else
#endif
return pValue1Result;
}
/**
* Performs a bitwise left shift on a 128-bit unsigned integer value, assigning
* the result to it.
*
* @returns pValue1Result.
* @param pValue1Result The first value and result.
* @param cBits The number of bits to shift.
*/
{
/** @todo #if ARCH_BITS >= 64 */
if (cBits > 0)
{
/* (left shift) */
if (cBits >= 128)
else if (cBits >= 64)
{
pValueResult->s.Lo = 0;
}
else
{
}
}
else if (cBits < 0)
{
/* (right shift) */
if (cBits >= 128)
else if (cBits >= 64)
{
pValueResult->s.Hi = 0;
}
else
{
}
}
return pValueResult;
}
/**
* Performs a bitwise left shift on a 128-bit unsigned integer value, assigning
* the result to it.
*
* @returns pValue1Result.
* @param pValue1Result The first value and result.
* @param cBits The number of bits to shift.
*/
{
}
/**
* Performs a bitwise NOT on a 128-bit unsigned integer value, assigning the
* result to it.
*
* @returns pValueResult
* @param pValueResult The value and result.
*/
{
#if ARCH_BITS >= 64
#else
#endif
return pValueResult;
}
/**
* Performs a boolean NOT on a 128-bit unsigned integer value, assigning the
* result to it.
*
* @returns pValueResult
* @param pValueResult The value and result.
*/
{
}
/**
* Compares two 128-bit unsigned integer values.
*
* @retval 0 if equal.
* @retval -1 if the first value is smaller than the second.
* @retval 1 if the first value is larger than the second.
*
* @param pValue1 The first value.
* @param pValue2 The second value.
*/
{
#if ARCH_BITS >= 64
return 0;
#else
return 0;
#endif
}
/**
* Tests if a 128-bit unsigned integer value is smaller than another.
*
* @returns true if the first value is smaller, false if not.
* @param pValue1 The first value.
* @param pValue2 The second value.
*/
{
#if ARCH_BITS >= 64
#else
#endif
}
/**
* Tests if a 128-bit unsigned integer value is larger than another.
*
* @returns true if the first value is larger, false if not.
* @param pValue1 The first value.
* @param pValue2 The second value.
*/
{
#if ARCH_BITS >= 64
#else
#endif
}
/**
* Tests if a 128-bit unsigned integer value is larger or equal than another.
*
* @returns true if the first value is larger or equal, false if not.
* @param pValue1 The first value.
* @param pValue2 The second value.
*/
{
#if ARCH_BITS >= 64
#else
#endif
}
/**
* Tests if two 128-bit unsigned integer values not equal.
*
* @returns true if equal, false if not equal.
* @param pValue1 The first value.
* @param pValue2 The second value.
*/
{
#if ARCH_BITS >= 64
#else
#endif
}
/**
* Tests if two 128-bit unsigned integer values are not equal.
*
* @returns true if not equal, false if equal.
* @param pValue1 The first value.
* @param pValue2 The second value.
*/
{
}
/**
* Sets a bit in a 128-bit unsigned integer type.
*
* @returns pValueResult.
* @param pValueResult The input and output value.
* @param iBit The bit to set.
*/
{
if (iBit < 64)
{
#if ARCH_BITS >= 64
#else
if (iBit < 32)
else
#endif
}
else if (iBit < 128)
{
#if ARCH_BITS >= 64
#else
if (iBit < 96)
else
#endif
}
return pValueResult;
}
/**
* Sets a bit in a 128-bit unsigned integer type.
*
* @returns pValueResult.
* @param pValueResult The input and output value.
* @param iBit The bit to set.
*/
{
if (iBit < 64)
{
#if ARCH_BITS >= 64
#else
if (iBit < 32)
else
#endif
}
else if (iBit < 128)
{
#if ARCH_BITS >= 64
#else
if (iBit < 96)
else
#endif
}
return pValueResult;
}
/**
* Tests if a bit in a 128-bit unsigned integer value is set.
*
* @returns pValueResult.
* @param pValueResult The input and output value.
* @param iBit The bit to test.
*/
{
bool fRc;
if (iBit < 64)
{
#if ARCH_BITS >= 64
#else
if (iBit < 32)
else
#endif
}
else if (iBit < 128)
{
#if ARCH_BITS >= 64
#else
if (iBit < 96)
else
#endif
}
else
fRc = false;
return fRc;
}
/**
* Set a range of bits a 128-bit unsigned integer value.
*
* @returns pValueResult.
* @param pValueResult The input and output value.
* @param iFirstBit The first bit to test.
* @param cBits The number of bits to set.
*/
DECLINLINE(PRTUINT128U) RTUInt128BitSetRange(PRTUINT128U pValueResult, unsigned iFirstBit, unsigned cBits)
{
/* bounds check & fix. */
if (iFirstBit < 128)
{
#if ARCH_BITS >= 64
else
#else
else
#endif
while (cBits-- > 0)
}
return pValueResult;
}
/**
* Test if all the bits of a 128-bit unsigned integer value are set.
*
* @returns true if they are, false if they aren't.
* @param pValue The input and output value.
*/
{
#if ARCH_BITS >= 64
#else
#endif
}
/**
* Test if all the bits of a 128-bit unsigned integer value are clear.
*
* @returns true if they are, false if they aren't.
* @param pValue The input and output value.
*/
{
#if ARCH_BITS >= 64
#else
#endif
}
{
{
else
}
else
{
else
}
return cBits;
}
/**
* Divides a 128-bit unsigned integer value by another, returning both quotient
* and remainder.
*
* @returns pQuotient, NULL if pValue2 is 0.
* @param pQuotient Where to return the quotient.
* @param pRemainder Where to return the remainder.
* @param pValue1 The dividend value.
* @param pValue2 The divisor value.
*/
DECLINLINE(PRTUINT128U) RTUInt128DivRem(PRTUINT128U pQuotient, PRTUINT128U pRemainder, PCRTUINT128U pValue1, PCRTUINT128U pValue2)
{
int iDiff;
/*
* Sort out all the special cases first.
*/
/* Divide by zero or 1? */
{
return NULL;
{
return pQuotient;
}
/** @todo RTUint128DivModBy64 */
}
/* Dividend is smaller? */
if (iDiff < 0)
{
*pRemainder = *pValue1;
}
/* The values are equal? */
else if (iDiff == 0)
{
}
else
{
/*
* Prepare.
*/
if (iBitAdder)
{
{
iBitAdder--;
}
}
else
NormDivisor = *pValue2;
*pRemainder = *pValue1;
/*
* Do the division.
*/
{
for (;;)
{
{
}
break;
iBitAdder--;
}
}
}
return pQuotient;
}
/** @} */
#endif