Skip to content

Commit

Permalink
CLib: Add short multiply/shift support
Browse files Browse the repository at this point in the history
In order to build ACPICA EFI tools with EDK-II on Windows, 64-bit
multiply/shift supports are also required to be implemented. Otherwise,
MSVC complains:
 acpidump.lib(utstrtoul64.obj) : error LNK2001: unresolved external symbol __allmul
 acpidump.lib(uthex.obj) : error LNK2001: unresolved external symbol __aullshr

Note:
1. This patch also splits _EDK2_EFI from _GNU_EFI as they might have
   different math64 supports.
2. Support of gcc math64 is not included in this patch.
3. Support of EDK2 arch independent math64 is done via linking to BaseLib.

This patch fixes this issue. Reported by Shao Ming, fixed by Lv Zheng.

Tested-by: "Shao, Ming" <smbest163@163.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
  • Loading branch information
Lv Zheng committed Jul 7, 2017
1 parent 33cd54c commit e6a634a
Show file tree
Hide file tree
Showing 22 changed files with 391 additions and 42 deletions.
4 changes: 3 additions & 1 deletion source/components/utilities/uthex.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,10 @@ AcpiUtHexToAsciiChar (
UINT64 Integer,
UINT32 Position)
{
UINT64 Index;

return (AcpiGbl_HexToAscii[(Integer >> Position) & 0xF]);
AcpiUtShortShiftRight (Integer, Position, &Index);
return (AcpiGbl_HexToAscii[Index & 0xF]);
}


Expand Down
261 changes: 251 additions & 10 deletions source/components/utilities/utmath.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,16 +156,6 @@
#define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME ("utmath")

/*
* Optional support for 64-bit double-precision integer divide. This code
* is configurable and is implemented in order to support 32-bit kernel
* environments where a 64-bit double-precision math library is not available.
*
* Support for a more normal 64-bit divide/modulo (with check for a divide-
* by-zero) appears after this optional section of code.
*/
#ifndef ACPI_USE_NATIVE_DIVIDE

/* Structures used only for 64-bit divide */

typedef struct uint64_struct
Expand All @@ -182,6 +172,257 @@ typedef union uint64_overlay

} UINT64_OVERLAY;

/*
* Optional support for 64-bit double-precision integer multiply and shift.
* This code is configurable and is implemented in order to support 32-bit
* kernel environments where a 64-bit double-precision math library is not
* available.
*/
#ifndef ACPI_USE_NATIVE_MATH64

/*******************************************************************************
*
* FUNCTION: AcpiUtShortMultiply
*
* PARAMETERS: Multiplicand - 64-bit multiplicand
* Multiplier - 32-bit multiplier
* OutProduct - Pointer to where the product is returned
*
* DESCRIPTION: Perform a short multiply.
*
******************************************************************************/

ACPI_STATUS
AcpiUtShortMultiply (
UINT64 Multiplicand,
UINT32 Multiplier,
UINT64 *OutProduct)
{
UINT64_OVERLAY MultiplicandOvl;
UINT64_OVERLAY Product;
UINT32 Carry32;


ACPI_FUNCTION_TRACE (UtShortMultiply);


MultiplicandOvl.Full = Multiplicand;

/*
* The Product is 64 bits, the carry is always 32 bits,
* and is generated by the second multiply.
*/
ACPI_MUL_64_BY_32 (0, MultiplicandOvl.Part.Hi, Multiplier,
Product.Part.Hi, Carry32);

ACPI_MUL_64_BY_32 (0, MultiplicandOvl.Part.Lo, Multiplier,
Product.Part.Lo, Carry32);

Product.Part.Hi += Carry32;

/* Return only what was requested */

if (OutProduct)
{
*OutProduct = Product.Full;
}

return_ACPI_STATUS (AE_OK);
}


/*******************************************************************************
*
* FUNCTION: AcpiUtShortShiftLeft
*
* PARAMETERS: Operand - 64-bit shift operand
* Count - 32-bit shift count
* OutResult - Pointer to where the result is returned
*
* DESCRIPTION: Perform a short left shift.
*
******************************************************************************/

ACPI_STATUS
AcpiUtShortShiftLeft (
UINT64 Operand,
UINT32 Count,
UINT64 *OutResult)
{
UINT64_OVERLAY OperandOvl;


ACPI_FUNCTION_TRACE (UtShortShiftLeft);


OperandOvl.Full = Operand;

if ((Count & 63) >= 32)
{
OperandOvl.Part.Hi = OperandOvl.Part.Lo;
OperandOvl.Part.Lo ^= OperandOvl.Part.Lo;
Count = (Count & 63) - 32;
}
ACPI_SHIFT_LEFT_64_BY_32 (OperandOvl.Part.Hi,
OperandOvl.Part.Lo, Count);

/* Return only what was requested */

if (OutResult)
{
*OutResult = OperandOvl.Full;
}

return_ACPI_STATUS (AE_OK);
}

/*******************************************************************************
*
* FUNCTION: AcpiUtShortShiftRight
*
* PARAMETERS: Operand - 64-bit shift operand
* Count - 32-bit shift count
* OutResult - Pointer to where the result is returned
*
* DESCRIPTION: Perform a short right shift.
*
******************************************************************************/

ACPI_STATUS
AcpiUtShortShiftRight (
UINT64 Operand,
UINT32 Count,
UINT64 *OutResult)
{
UINT64_OVERLAY OperandOvl;


ACPI_FUNCTION_TRACE (UtShortShiftRight);


OperandOvl.Full = Operand;

if ((Count & 63) >= 32)
{
OperandOvl.Part.Lo = OperandOvl.Part.Hi;
OperandOvl.Part.Hi ^= OperandOvl.Part.Hi;
Count = (Count & 63) - 32;
}
ACPI_SHIFT_RIGHT_64_BY_32 (OperandOvl.Part.Hi,
OperandOvl.Part.Lo, Count);

/* Return only what was requested */

if (OutResult)
{
*OutResult = OperandOvl.Full;
}

return_ACPI_STATUS (AE_OK);
}
#else

/*******************************************************************************
*
* FUNCTION: AcpiUtShortMultiply
*
* PARAMETERS: See function headers above
*
* DESCRIPTION: Native version of the UtShortMultiply function.
*
******************************************************************************/

ACPI_STATUS
AcpiUtShortMultiply (
UINT64 Multiplicand,
UINT32 Multiplier,
UINT64 *OutProduct)
{

ACPI_FUNCTION_TRACE (UtShortMultiply);


/* Return only what was requested */

if (OutProduct)
{
*OutProduct = Multiplicand * Multiplier;
}

return_ACPI_STATUS (AE_OK);
}

/*******************************************************************************
*
* FUNCTION: AcpiUtShortShiftLeft
*
* PARAMETERS: See function headers above
*
* DESCRIPTION: Native version of the UtShortShiftLeft function.
*
******************************************************************************/

ACPI_STATUS
AcpiUtShortShiftLeft (
UINT64 Operand,
UINT32 Count,
UINT64 *OutResult)
{

ACPI_FUNCTION_TRACE (UtShortShiftLeft);


/* Return only what was requested */

if (OutResult)
{
*OutResult = Operand << Count;
}

return_ACPI_STATUS (AE_OK);
}

/*******************************************************************************
*
* FUNCTION: AcpiUtShortShiftRight
*
* PARAMETERS: See function headers above
*
* DESCRIPTION: Native version of the UtShortShiftRight function.
*
******************************************************************************/

ACPI_STATUS
AcpiUtShortShiftRight (
UINT64 Operand,
UINT32 Count,
UINT64 *OutResult)
{

ACPI_FUNCTION_TRACE (UtShortShiftRight);


/* Return only what was requested */

if (OutResult)
{
*OutResult = Operand >> Count;
}

return_ACPI_STATUS (AE_OK);
}
#endif

/*
* Optional support for 64-bit double-precision integer divide. This code
* is configurable and is implemented in order to support 32-bit kernel
* environments where a 64-bit double-precision math library is not available.
*
* Support for a more normal 64-bit divide/modulo (with check for a divide-
* by-zero) appears after this optional section of code.
*/
#ifndef ACPI_USE_NATIVE_DIVIDE


/*******************************************************************************
*
Expand Down
2 changes: 1 addition & 1 deletion source/components/utilities/utprint.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ AcpiUtScanNumber (

while (isdigit ((int) *String))
{
Number *= 10;
AcpiUtShortMultiply (Number, 10, &Number);
Number += *(String++) - '0';
}

Expand Down
8 changes: 4 additions & 4 deletions source/components/utilities/utstrtoul64.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,8 +419,8 @@ AcpiUtStrtoulBase10 (

/* Convert and insert (add) the decimal digit */

NextValue =
(ReturnValue * 10) + (AsciiDigit - ACPI_ASCII_ZERO);
AcpiUtShortMultiply (ReturnValue, 10, &NextValue);
NextValue += (AsciiDigit - ACPI_ASCII_ZERO);

/* Check for overflow (32 or 64 bit) - return current converted value */

Expand Down Expand Up @@ -486,8 +486,8 @@ AcpiUtStrtoulBase16 (

/* Convert and insert the hex digit */

ReturnValue =
(ReturnValue << 4) | AcpiUtAsciiCharToHex (AsciiDigit);
AcpiUtShortShiftLeft (ReturnValue, 4, &ReturnValue);
ReturnValue |= AcpiUtAsciiCharToHex (AsciiDigit);

String++;
ValidDigits++;
Expand Down
1 change: 1 addition & 0 deletions source/include/actypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ typedef UINT64 ACPI_PHYSICAL_ADDRESS;
#define ACPI_MAX_PTR ACPI_UINT64_MAX
#define ACPI_SIZE_MAX ACPI_UINT64_MAX
#define ACPI_USE_NATIVE_DIVIDE /* Has native 64-bit integer support */
#define ACPI_USE_NATIVE_MATH64 /* Has native 64-bit integer support */

/*
* In the case of the Itanium Processor Family (IPF), the hardware does not
Expand Down
18 changes: 18 additions & 0 deletions source/include/acutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,24 @@ AcpiUtShortDivide (
UINT64 *OutQuotient,
UINT32 *OutRemainder);

ACPI_STATUS
AcpiUtShortMultiply (
UINT64 InMultiplicand,
UINT32 Multiplier,
UINT64 *Outproduct);

ACPI_STATUS
AcpiUtShortShiftLeft (
UINT64 Operand,
UINT32 Count,
UINT64 *OutResult);

ACPI_STATUS
AcpiUtShortShiftRight (
UINT64 Operand,
UINT32 Count,
UINT64 *OutResult);


/*
* utmisc
Expand Down
1 change: 1 addition & 0 deletions source/include/platform/accygwin.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@
#define COMPILER_DEPENDENT_INT64 long long
#define COMPILER_DEPENDENT_UINT64 unsigned long long
#define ACPI_USE_NATIVE_DIVIDE
#define ACPI_USE_NATIVE_MATH64
#endif

#ifndef __cdecl
Expand Down
1 change: 1 addition & 0 deletions source/include/platform/acdragonfly.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@
#else
#define ACPI_MACHINE_WIDTH 32
#define ACPI_USE_NATIVE_DIVIDE
#define ACPI_USE_NATIVE_MATH64
#endif

#define ACPI_UINTPTR_T uintptr_t
Expand Down
Loading

0 comments on commit e6a634a

Please sign in to comment.