|
@@ -47,15 +47,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 {
|
|
|
u32 lo;
|
|
@@ -69,6 +60,217 @@ 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: acpi_ut_short_multiply
|
|
|
+ *
|
|
|
+ * PARAMETERS: multiplicand - 64-bit multiplicand
|
|
|
+ * multiplier - 32-bit multiplier
|
|
|
+ * out_product - Pointer to where the product is returned
|
|
|
+ *
|
|
|
+ * DESCRIPTION: Perform a short multiply.
|
|
|
+ *
|
|
|
+ ******************************************************************************/
|
|
|
+
|
|
|
+acpi_status
|
|
|
+acpi_ut_short_multiply(u64 multiplicand, u32 multiplier, u64 *out_product)
|
|
|
+{
|
|
|
+ union uint64_overlay multiplicand_ovl;
|
|
|
+ union uint64_overlay product;
|
|
|
+ u32 carry32;
|
|
|
+
|
|
|
+ ACPI_FUNCTION_TRACE(ut_short_multiply);
|
|
|
+
|
|
|
+ multiplicand_ovl.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, multiplicand_ovl.part.hi, multiplier,
|
|
|
+ product.part.hi, carry32);
|
|
|
+
|
|
|
+ ACPI_MUL_64_BY_32(0, multiplicand_ovl.part.lo, multiplier,
|
|
|
+ product.part.lo, carry32);
|
|
|
+
|
|
|
+ product.part.hi += carry32;
|
|
|
+
|
|
|
+ /* Return only what was requested */
|
|
|
+
|
|
|
+ if (out_product) {
|
|
|
+ *out_product = product.full;
|
|
|
+ }
|
|
|
+
|
|
|
+ return_ACPI_STATUS(AE_OK);
|
|
|
+}
|
|
|
+
|
|
|
+/*******************************************************************************
|
|
|
+ *
|
|
|
+ * FUNCTION: acpi_ut_short_shift_left
|
|
|
+ *
|
|
|
+ * PARAMETERS: operand - 64-bit shift operand
|
|
|
+ * count - 32-bit shift count
|
|
|
+ * out_result - Pointer to where the result is returned
|
|
|
+ *
|
|
|
+ * DESCRIPTION: Perform a short left shift.
|
|
|
+ *
|
|
|
+ ******************************************************************************/
|
|
|
+
|
|
|
+acpi_status acpi_ut_short_shift_left(u64 operand, u32 count, u64 *out_result)
|
|
|
+{
|
|
|
+ union uint64_overlay operand_ovl;
|
|
|
+
|
|
|
+ ACPI_FUNCTION_TRACE(ut_short_shift_left);
|
|
|
+
|
|
|
+ operand_ovl.full = operand;
|
|
|
+
|
|
|
+ if ((count & 63) >= 32) {
|
|
|
+ operand_ovl.part.hi = operand_ovl.part.lo;
|
|
|
+ operand_ovl.part.lo ^= operand_ovl.part.lo;
|
|
|
+ count = (count & 63) - 32;
|
|
|
+ }
|
|
|
+ ACPI_SHIFT_LEFT_64_BY_32(operand_ovl.part.hi,
|
|
|
+ operand_ovl.part.lo, count);
|
|
|
+
|
|
|
+ /* Return only what was requested */
|
|
|
+
|
|
|
+ if (out_result) {
|
|
|
+ *out_result = operand_ovl.full;
|
|
|
+ }
|
|
|
+
|
|
|
+ return_ACPI_STATUS(AE_OK);
|
|
|
+}
|
|
|
+
|
|
|
+/*******************************************************************************
|
|
|
+ *
|
|
|
+ * FUNCTION: acpi_ut_short_shift_right
|
|
|
+ *
|
|
|
+ * PARAMETERS: operand - 64-bit shift operand
|
|
|
+ * count - 32-bit shift count
|
|
|
+ * out_result - Pointer to where the result is returned
|
|
|
+ *
|
|
|
+ * DESCRIPTION: Perform a short right shift.
|
|
|
+ *
|
|
|
+ ******************************************************************************/
|
|
|
+
|
|
|
+acpi_status acpi_ut_short_shift_right(u64 operand, u32 count, u64 *out_result)
|
|
|
+{
|
|
|
+ union uint64_overlay operand_ovl;
|
|
|
+
|
|
|
+ ACPI_FUNCTION_TRACE(ut_short_shift_right);
|
|
|
+
|
|
|
+ operand_ovl.full = operand;
|
|
|
+
|
|
|
+ if ((count & 63) >= 32) {
|
|
|
+ operand_ovl.part.lo = operand_ovl.part.hi;
|
|
|
+ operand_ovl.part.hi ^= operand_ovl.part.hi;
|
|
|
+ count = (count & 63) - 32;
|
|
|
+ }
|
|
|
+ ACPI_SHIFT_RIGHT_64_BY_32(operand_ovl.part.hi,
|
|
|
+ operand_ovl.part.lo, count);
|
|
|
+
|
|
|
+ /* Return only what was requested */
|
|
|
+
|
|
|
+ if (out_result) {
|
|
|
+ *out_result = operand_ovl.full;
|
|
|
+ }
|
|
|
+
|
|
|
+ return_ACPI_STATUS(AE_OK);
|
|
|
+}
|
|
|
+#else
|
|
|
+
|
|
|
+/*******************************************************************************
|
|
|
+ *
|
|
|
+ * FUNCTION: acpi_ut_short_multiply
|
|
|
+ *
|
|
|
+ * PARAMETERS: See function headers above
|
|
|
+ *
|
|
|
+ * DESCRIPTION: Native version of the ut_short_multiply function.
|
|
|
+ *
|
|
|
+ ******************************************************************************/
|
|
|
+
|
|
|
+acpi_status
|
|
|
+acpi_ut_short_multiply(u64 multiplicand, u32 multiplier, u64 *out_product)
|
|
|
+{
|
|
|
+
|
|
|
+ ACPI_FUNCTION_TRACE(ut_short_multiply);
|
|
|
+
|
|
|
+ /* Return only what was requested */
|
|
|
+
|
|
|
+ if (out_product) {
|
|
|
+ *out_product = multiplicand * multiplier;
|
|
|
+ }
|
|
|
+
|
|
|
+ return_ACPI_STATUS(AE_OK);
|
|
|
+}
|
|
|
+
|
|
|
+/*******************************************************************************
|
|
|
+ *
|
|
|
+ * FUNCTION: acpi_ut_short_shift_left
|
|
|
+ *
|
|
|
+ * PARAMETERS: See function headers above
|
|
|
+ *
|
|
|
+ * DESCRIPTION: Native version of the ut_short_shift_left function.
|
|
|
+ *
|
|
|
+ ******************************************************************************/
|
|
|
+
|
|
|
+acpi_status acpi_ut_short_shift_left(u64 operand, u32 count, u64 *out_result)
|
|
|
+{
|
|
|
+
|
|
|
+ ACPI_FUNCTION_TRACE(ut_short_shift_left);
|
|
|
+
|
|
|
+ /* Return only what was requested */
|
|
|
+
|
|
|
+ if (out_result) {
|
|
|
+ *out_result = operand << count;
|
|
|
+ }
|
|
|
+
|
|
|
+ return_ACPI_STATUS(AE_OK);
|
|
|
+}
|
|
|
+
|
|
|
+/*******************************************************************************
|
|
|
+ *
|
|
|
+ * FUNCTION: acpi_ut_short_shift_right
|
|
|
+ *
|
|
|
+ * PARAMETERS: See function headers above
|
|
|
+ *
|
|
|
+ * DESCRIPTION: Native version of the ut_short_shift_right function.
|
|
|
+ *
|
|
|
+ ******************************************************************************/
|
|
|
+
|
|
|
+acpi_status acpi_ut_short_shift_right(u64 operand, u32 count, u64 *out_result)
|
|
|
+{
|
|
|
+
|
|
|
+ ACPI_FUNCTION_TRACE(ut_short_shift_right);
|
|
|
+
|
|
|
+ /* Return only what was requested */
|
|
|
+
|
|
|
+ if (out_result) {
|
|
|
+ *out_result = 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
|
|
|
+
|
|
|
/*******************************************************************************
|
|
|
*
|
|
|
* FUNCTION: acpi_ut_short_divide
|
|
@@ -258,6 +460,7 @@ acpi_ut_divide(u64 in_dividend,
|
|
|
}
|
|
|
|
|
|
#else
|
|
|
+
|
|
|
/*******************************************************************************
|
|
|
*
|
|
|
* FUNCTION: acpi_ut_short_divide, acpi_ut_divide
|
|
@@ -272,6 +475,7 @@ acpi_ut_divide(u64 in_dividend,
|
|
|
* perform the divide.
|
|
|
*
|
|
|
******************************************************************************/
|
|
|
+
|
|
|
acpi_status
|
|
|
acpi_ut_short_divide(u64 in_dividend,
|
|
|
u32 divisor, u64 *out_quotient, u32 *out_remainder)
|