cloudinit/vendor/github.com/sigma/vmw-guestinfo/include/mul64.h

144 lines
4.1 KiB
C
Raw Permalink Normal View History

/*********************************************************
* Copyright (C) 2003-2014 VMware, Inc. All rights reserved.
*
* This program 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 version 2.1 and no later version.
*
* This program 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 Lesser GNU General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*********************************************************/
/*********************************************************
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
* and no later version. You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* http://www.opensource.org/licenses/cddl1.php
*
* See the License for the specific language governing permissions
* and limitations under the License.
*
*********************************************************/
/*
* mul64.h
*
* Integer by fixed point multiplication, with rounding.
*
* These routines are implemented in assembly language for most
* supported platforms. This file has plain C fallback versions.
*/
#ifndef _MUL64_H_
#define _MUL64_H_
#define INCLUDE_ALLOW_USERLEVEL
#define INCLUDE_ALLOW_MODULE
#define INCLUDE_ALLOW_VMMON
#define INCLUDE_ALLOW_VMK_MODULE
#define INCLUDE_ALLOW_VMKERNEL
#define INCLUDE_ALLOW_DISTRIBUTE
#define INCLUDE_ALLOW_VMCORE
#include "includeCheck.h"
#include "vm_basic_asm.h"
#ifdef MUL64_NO_ASM
/*
*-----------------------------------------------------------------------------
*
* Mul64x3264 --
*
* Unsigned integer by fixed point multiplication, with rounding:
* result = floor(multiplicand * multiplier * 2**(-shift) + 0.5)
*
* Unsigned 64-bit integer multiplicand.
* Unsigned 32-bit fixed point multiplier, represented as
* (multiplier, shift), where shift < 64.
*
* Result:
* Unsigned 64-bit integer product.
*
*-----------------------------------------------------------------------------
*/
static INLINE uint64
Mul64x3264(uint64 multiplicand, uint32 multiplier, uint32 shift)
{
uint64 lo, hi, lo2, hi2;
unsigned carry;
// ASSERT(shift >= 0 && shift < 64);
lo = (multiplicand & 0xffffffff) * multiplier;
hi = (multiplicand >> 32) * multiplier;
lo2 = lo + (hi << 32);
carry = lo2 < lo;
hi2 = (hi >> 32) + carry;
if (shift == 0) {
return lo2;
} else {
return (lo2 >> shift) + (hi2 << (64 - shift)) +
((lo2 >> (shift - 1)) & 1);
}
}
/*
*-----------------------------------------------------------------------------
*
* Muls64x32s64 --
*
* Signed integer by fixed point multiplication, with rounding:
* result = floor(multiplicand * multiplier * 2**(-shift) + 0.5)
*
* Signed 64-bit integer multiplicand.
* Unsigned 32-bit fixed point multiplier, represented as
* (multiplier, shift), where shift < 64.
*
* Result:
* Signed 64-bit integer product.
*
*-----------------------------------------------------------------------------
*/
static INLINE int64
Muls64x32s64(int64 multiplicand, uint32 multiplier, uint32 shift)
{
uint64 lo, hi, lo2, hi2;
unsigned carry;
// ASSERT(shift >= 0 && shift < 64);
hi = ((uint64)multiplicand >> 32) * multiplier;
if (multiplicand < 0) {
hi -= (uint64)multiplier << 32;
}
lo = ((uint64)multiplicand & 0xffffffff) * multiplier;
lo2 = lo + (hi << 32);
carry = lo2 < lo;
hi2 = (((int64)hi >> 32) + carry);
if (shift == 0) {
return lo2;
} else {
return (lo2 >> shift) + (hi2 << (64 - shift)) +
((lo2 >> (shift - 1)) & 1);
}
}
#endif
#endif // _MUL64_NOASM_H_