184493Smsmith/******************************************************************************* 284493Smsmith * 384493Smsmith * Module Name: utmath - Integer math support routines 484493Smsmith * 584493Smsmith ******************************************************************************/ 684493Smsmith 7316303Sjkim/****************************************************************************** 8316303Sjkim * 9316303Sjkim * 1. Copyright Notice 10316303Sjkim * 11316303Sjkim * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp. 1284493Smsmith * All rights reserved. 1384493Smsmith * 14316303Sjkim * 2. License 15316303Sjkim * 16316303Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property 17316303Sjkim * rights. You may have additional license terms from the party that provided 18316303Sjkim * you this software, covering your right to use that party's intellectual 19316303Sjkim * property rights. 20316303Sjkim * 21316303Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22316303Sjkim * copy of the source code appearing in this file ("Covered Code") an 23316303Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24316303Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy, 25316303Sjkim * make derivatives, distribute, use and display any portion of the Covered 26316303Sjkim * Code in any form, with the right to sublicense such rights; and 27316303Sjkim * 28316303Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29316303Sjkim * license (with the right to sublicense), under only those claims of Intel 30316303Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell, 31316303Sjkim * offer to sell, and import the Covered Code and derivative works thereof 32316303Sjkim * solely to the minimum extent necessary to exercise the above copyright 33316303Sjkim * license, and in no event shall the patent license extend to any additions 34316303Sjkim * to or modifications of the Original Intel Code. No other license or right 35316303Sjkim * is granted directly or by implication, estoppel or otherwise; 36316303Sjkim * 37316303Sjkim * The above copyright and patent license is granted only if the following 38316303Sjkim * conditions are met: 39316303Sjkim * 40316303Sjkim * 3. Conditions 41316303Sjkim * 42316303Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43316303Sjkim * Redistribution of source code of any substantial portion of the Covered 44316303Sjkim * Code or modification with rights to further distribute source must include 45316303Sjkim * the above Copyright Notice, the above License, this list of Conditions, 46316303Sjkim * and the following Disclaimer and Export Compliance provision. In addition, 47316303Sjkim * Licensee must cause all Covered Code to which Licensee contributes to 48316303Sjkim * contain a file documenting the changes Licensee made to create that Covered 49316303Sjkim * Code and the date of any change. Licensee must include in that file the 50316303Sjkim * documentation of any changes made by any predecessor Licensee. Licensee 51316303Sjkim * must include a prominent statement that the modification is derived, 52316303Sjkim * directly or indirectly, from Original Intel Code. 53316303Sjkim * 54316303Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55316303Sjkim * Redistribution of source code of any substantial portion of the Covered 56316303Sjkim * Code or modification without rights to further distribute source must 57316303Sjkim * include the following Disclaimer and Export Compliance provision in the 58316303Sjkim * documentation and/or other materials provided with distribution. In 59316303Sjkim * addition, Licensee may not authorize further sublicense of source of any 60316303Sjkim * portion of the Covered Code, and must include terms to the effect that the 61316303Sjkim * license from Licensee to its licensee is limited to the intellectual 62316303Sjkim * property embodied in the software Licensee provides to its licensee, and 63316303Sjkim * not to intellectual property embodied in modifications its licensee may 64316303Sjkim * make. 65316303Sjkim * 66316303Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any 67316303Sjkim * substantial portion of the Covered Code or modification must reproduce the 68316303Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance 69316303Sjkim * provision in the documentation and/or other materials provided with the 70316303Sjkim * distribution. 71316303Sjkim * 72316303Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original 73316303Sjkim * Intel Code. 74316303Sjkim * 75316303Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76316303Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or 77316303Sjkim * other dealings in products derived from or relating to the Covered Code 78316303Sjkim * without prior written authorization from Intel. 79316303Sjkim * 80316303Sjkim * 4. Disclaimer and Export Compliance 81316303Sjkim * 82316303Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83316303Sjkim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84316303Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85316303Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86316303Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87316303Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88316303Sjkim * PARTICULAR PURPOSE. 89316303Sjkim * 90316303Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91316303Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92316303Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93316303Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94316303Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95316303Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96316303Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97316303Sjkim * LIMITED REMEDY. 98316303Sjkim * 99316303Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this 100316303Sjkim * software or system incorporating such software without first obtaining any 101316303Sjkim * required license or other approval from the U. S. Department of Commerce or 102316303Sjkim * any other agency or department of the United States Government. In the 103316303Sjkim * event Licensee exports any such software from the United States or 104316303Sjkim * re-exports any such software from a foreign destination, Licensee shall 105316303Sjkim * ensure that the distribution and export/re-export of the software is in 106316303Sjkim * compliance with all laws, regulations, orders, or other restrictions of the 107316303Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108316303Sjkim * any of its subsidiaries will export/re-export any technical data, process, 109316303Sjkim * software, or service, directly or indirectly, to any country for which the 110316303Sjkim * United States government or any agency thereof requires an export license, 111316303Sjkim * other governmental approval, or letter of assurance, without first obtaining 112316303Sjkim * such license, approval or letter. 113316303Sjkim * 114316303Sjkim ***************************************************************************** 115316303Sjkim * 116316303Sjkim * Alternatively, you may choose to be licensed under the terms of the 117316303Sjkim * following license: 118316303Sjkim * 119217365Sjkim * Redistribution and use in source and binary forms, with or without 120217365Sjkim * modification, are permitted provided that the following conditions 121217365Sjkim * are met: 122217365Sjkim * 1. Redistributions of source code must retain the above copyright 123217365Sjkim * notice, this list of conditions, and the following disclaimer, 124217365Sjkim * without modification. 125217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 127217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 128217365Sjkim * including a substantially similar Disclaimer requirement for further 129217365Sjkim * binary redistribution. 130217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 131217365Sjkim * of any contributors may be used to endorse or promote products derived 132217365Sjkim * from this software without specific prior written permission. 13384493Smsmith * 134316303Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135316303Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136316303Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137316303Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138316303Sjkim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139316303Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140316303Sjkim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141316303Sjkim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142316303Sjkim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143316303Sjkim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144316303Sjkim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145316303Sjkim * 146316303Sjkim * Alternatively, you may choose to be licensed under the terms of the 147217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 148217365Sjkim * Software Foundation. 14984493Smsmith * 150316303Sjkim *****************************************************************************/ 15184493Smsmith 152193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 153193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 15484493Smsmith 15584493Smsmith 15684493Smsmith#define _COMPONENT ACPI_UTILITIES 15791116Smsmith ACPI_MODULE_NAME ("utmath") 15884493Smsmith 159212761Sjkim/* Structures used only for 64-bit divide */ 160212761Sjkim 161212761Sjkimtypedef struct uint64_struct 162212761Sjkim{ 163212761Sjkim UINT32 Lo; 164212761Sjkim UINT32 Hi; 165212761Sjkim 166212761Sjkim} UINT64_STRUCT; 167212761Sjkim 168212761Sjkimtypedef union uint64_overlay 169212761Sjkim{ 170212761Sjkim UINT64 Full; 171212761Sjkim UINT64_STRUCT Part; 172212761Sjkim 173212761Sjkim} UINT64_OVERLAY; 174212761Sjkim 175322877Sjkim/* 176322877Sjkim * Optional support for 64-bit double-precision integer multiply and shift. 177322877Sjkim * This code is configurable and is implemented in order to support 32-bit 178322877Sjkim * kernel environments where a 64-bit double-precision math library is not 179322877Sjkim * available. 180322877Sjkim */ 181322877Sjkim#ifndef ACPI_USE_NATIVE_MATH64 182212761Sjkim 18384493Smsmith/******************************************************************************* 18484493Smsmith * 185322877Sjkim * FUNCTION: AcpiUtShortMultiply 186322877Sjkim * 187322877Sjkim * PARAMETERS: Multiplicand - 64-bit multiplicand 188322877Sjkim * Multiplier - 32-bit multiplier 189322877Sjkim * OutProduct - Pointer to where the product is returned 190322877Sjkim * 191322877Sjkim * DESCRIPTION: Perform a short multiply. 192322877Sjkim * 193322877Sjkim ******************************************************************************/ 194322877Sjkim 195322877SjkimACPI_STATUS 196322877SjkimAcpiUtShortMultiply ( 197322877Sjkim UINT64 Multiplicand, 198322877Sjkim UINT32 Multiplier, 199322877Sjkim UINT64 *OutProduct) 200322877Sjkim{ 201322877Sjkim UINT64_OVERLAY MultiplicandOvl; 202322877Sjkim UINT64_OVERLAY Product; 203322877Sjkim UINT32 Carry32; 204322877Sjkim 205322877Sjkim 206322877Sjkim ACPI_FUNCTION_TRACE (UtShortMultiply); 207322877Sjkim 208322877Sjkim 209322877Sjkim MultiplicandOvl.Full = Multiplicand; 210322877Sjkim 211322877Sjkim /* 212322877Sjkim * The Product is 64 bits, the carry is always 32 bits, 213322877Sjkim * and is generated by the second multiply. 214322877Sjkim */ 215322877Sjkim ACPI_MUL_64_BY_32 (0, MultiplicandOvl.Part.Hi, Multiplier, 216322877Sjkim Product.Part.Hi, Carry32); 217322877Sjkim 218322877Sjkim ACPI_MUL_64_BY_32 (0, MultiplicandOvl.Part.Lo, Multiplier, 219322877Sjkim Product.Part.Lo, Carry32); 220322877Sjkim 221322877Sjkim Product.Part.Hi += Carry32; 222322877Sjkim 223322877Sjkim /* Return only what was requested */ 224322877Sjkim 225322877Sjkim if (OutProduct) 226322877Sjkim { 227322877Sjkim *OutProduct = Product.Full; 228322877Sjkim } 229322877Sjkim 230322877Sjkim return_ACPI_STATUS (AE_OK); 231322877Sjkim} 232322877Sjkim 233322877Sjkim 234322877Sjkim/******************************************************************************* 235322877Sjkim * 236322877Sjkim * FUNCTION: AcpiUtShortShiftLeft 237322877Sjkim * 238322877Sjkim * PARAMETERS: Operand - 64-bit shift operand 239322877Sjkim * Count - 32-bit shift count 240322877Sjkim * OutResult - Pointer to where the result is returned 241322877Sjkim * 242322877Sjkim * DESCRIPTION: Perform a short left shift. 243322877Sjkim * 244322877Sjkim ******************************************************************************/ 245322877Sjkim 246322877SjkimACPI_STATUS 247322877SjkimAcpiUtShortShiftLeft ( 248322877Sjkim UINT64 Operand, 249322877Sjkim UINT32 Count, 250322877Sjkim UINT64 *OutResult) 251322877Sjkim{ 252322877Sjkim UINT64_OVERLAY OperandOvl; 253322877Sjkim 254322877Sjkim 255322877Sjkim ACPI_FUNCTION_TRACE (UtShortShiftLeft); 256322877Sjkim 257322877Sjkim 258322877Sjkim OperandOvl.Full = Operand; 259322877Sjkim 260322877Sjkim if ((Count & 63) >= 32) 261322877Sjkim { 262322877Sjkim OperandOvl.Part.Hi = OperandOvl.Part.Lo; 263327557Sjkim OperandOvl.Part.Lo = 0; 264322877Sjkim Count = (Count & 63) - 32; 265322877Sjkim } 266322877Sjkim ACPI_SHIFT_LEFT_64_BY_32 (OperandOvl.Part.Hi, 267322877Sjkim OperandOvl.Part.Lo, Count); 268322877Sjkim 269322877Sjkim /* Return only what was requested */ 270322877Sjkim 271322877Sjkim if (OutResult) 272322877Sjkim { 273322877Sjkim *OutResult = OperandOvl.Full; 274322877Sjkim } 275322877Sjkim 276322877Sjkim return_ACPI_STATUS (AE_OK); 277322877Sjkim} 278322877Sjkim 279322877Sjkim/******************************************************************************* 280322877Sjkim * 281322877Sjkim * FUNCTION: AcpiUtShortShiftRight 282322877Sjkim * 283322877Sjkim * PARAMETERS: Operand - 64-bit shift operand 284322877Sjkim * Count - 32-bit shift count 285322877Sjkim * OutResult - Pointer to where the result is returned 286322877Sjkim * 287322877Sjkim * DESCRIPTION: Perform a short right shift. 288322877Sjkim * 289322877Sjkim ******************************************************************************/ 290322877Sjkim 291322877SjkimACPI_STATUS 292322877SjkimAcpiUtShortShiftRight ( 293322877Sjkim UINT64 Operand, 294322877Sjkim UINT32 Count, 295322877Sjkim UINT64 *OutResult) 296322877Sjkim{ 297322877Sjkim UINT64_OVERLAY OperandOvl; 298322877Sjkim 299322877Sjkim 300322877Sjkim ACPI_FUNCTION_TRACE (UtShortShiftRight); 301322877Sjkim 302322877Sjkim 303322877Sjkim OperandOvl.Full = Operand; 304322877Sjkim 305322877Sjkim if ((Count & 63) >= 32) 306322877Sjkim { 307322877Sjkim OperandOvl.Part.Lo = OperandOvl.Part.Hi; 308327557Sjkim OperandOvl.Part.Hi = 0; 309322877Sjkim Count = (Count & 63) - 32; 310322877Sjkim } 311322877Sjkim ACPI_SHIFT_RIGHT_64_BY_32 (OperandOvl.Part.Hi, 312322877Sjkim OperandOvl.Part.Lo, Count); 313322877Sjkim 314322877Sjkim /* Return only what was requested */ 315322877Sjkim 316322877Sjkim if (OutResult) 317322877Sjkim { 318322877Sjkim *OutResult = OperandOvl.Full; 319322877Sjkim } 320322877Sjkim 321322877Sjkim return_ACPI_STATUS (AE_OK); 322322877Sjkim} 323322877Sjkim#else 324322877Sjkim 325322877Sjkim/******************************************************************************* 326322877Sjkim * 327322877Sjkim * FUNCTION: AcpiUtShortMultiply 328322877Sjkim * 329322877Sjkim * PARAMETERS: See function headers above 330322877Sjkim * 331322877Sjkim * DESCRIPTION: Native version of the UtShortMultiply function. 332322877Sjkim * 333322877Sjkim ******************************************************************************/ 334322877Sjkim 335322877SjkimACPI_STATUS 336322877SjkimAcpiUtShortMultiply ( 337322877Sjkim UINT64 Multiplicand, 338322877Sjkim UINT32 Multiplier, 339322877Sjkim UINT64 *OutProduct) 340322877Sjkim{ 341322877Sjkim 342322877Sjkim ACPI_FUNCTION_TRACE (UtShortMultiply); 343322877Sjkim 344322877Sjkim 345322877Sjkim /* Return only what was requested */ 346322877Sjkim 347322877Sjkim if (OutProduct) 348322877Sjkim { 349322877Sjkim *OutProduct = Multiplicand * Multiplier; 350322877Sjkim } 351322877Sjkim 352322877Sjkim return_ACPI_STATUS (AE_OK); 353322877Sjkim} 354322877Sjkim 355322877Sjkim/******************************************************************************* 356322877Sjkim * 357322877Sjkim * FUNCTION: AcpiUtShortShiftLeft 358322877Sjkim * 359322877Sjkim * PARAMETERS: See function headers above 360322877Sjkim * 361322877Sjkim * DESCRIPTION: Native version of the UtShortShiftLeft function. 362322877Sjkim * 363322877Sjkim ******************************************************************************/ 364322877Sjkim 365322877SjkimACPI_STATUS 366322877SjkimAcpiUtShortShiftLeft ( 367322877Sjkim UINT64 Operand, 368322877Sjkim UINT32 Count, 369322877Sjkim UINT64 *OutResult) 370322877Sjkim{ 371322877Sjkim 372322877Sjkim ACPI_FUNCTION_TRACE (UtShortShiftLeft); 373322877Sjkim 374322877Sjkim 375322877Sjkim /* Return only what was requested */ 376322877Sjkim 377322877Sjkim if (OutResult) 378322877Sjkim { 379322877Sjkim *OutResult = Operand << Count; 380322877Sjkim } 381322877Sjkim 382322877Sjkim return_ACPI_STATUS (AE_OK); 383322877Sjkim} 384322877Sjkim 385322877Sjkim/******************************************************************************* 386322877Sjkim * 387322877Sjkim * FUNCTION: AcpiUtShortShiftRight 388322877Sjkim * 389322877Sjkim * PARAMETERS: See function headers above 390322877Sjkim * 391322877Sjkim * DESCRIPTION: Native version of the UtShortShiftRight function. 392322877Sjkim * 393322877Sjkim ******************************************************************************/ 394322877Sjkim 395322877SjkimACPI_STATUS 396322877SjkimAcpiUtShortShiftRight ( 397322877Sjkim UINT64 Operand, 398322877Sjkim UINT32 Count, 399322877Sjkim UINT64 *OutResult) 400322877Sjkim{ 401322877Sjkim 402322877Sjkim ACPI_FUNCTION_TRACE (UtShortShiftRight); 403322877Sjkim 404322877Sjkim 405322877Sjkim /* Return only what was requested */ 406322877Sjkim 407322877Sjkim if (OutResult) 408322877Sjkim { 409322877Sjkim *OutResult = Operand >> Count; 410322877Sjkim } 411322877Sjkim 412322877Sjkim return_ACPI_STATUS (AE_OK); 413322877Sjkim} 414322877Sjkim#endif 415322877Sjkim 416322877Sjkim/* 417322877Sjkim * Optional support for 64-bit double-precision integer divide. This code 418322877Sjkim * is configurable and is implemented in order to support 32-bit kernel 419322877Sjkim * environments where a 64-bit double-precision math library is not available. 420322877Sjkim * 421322877Sjkim * Support for a more normal 64-bit divide/modulo (with check for a divide- 422322877Sjkim * by-zero) appears after this optional section of code. 423322877Sjkim */ 424322877Sjkim#ifndef ACPI_USE_NATIVE_DIVIDE 425322877Sjkim 426322877Sjkim 427322877Sjkim/******************************************************************************* 428322877Sjkim * 42984493Smsmith * FUNCTION: AcpiUtShortDivide 43084493Smsmith * 431138287Smarks * PARAMETERS: Dividend - 64-bit dividend 43284493Smsmith * Divisor - 32-bit divisor 43384493Smsmith * OutQuotient - Pointer to where the quotient is returned 43484493Smsmith * OutRemainder - Pointer to where the remainder is returned 43584493Smsmith * 43684493Smsmith * RETURN: Status (Checks for divide-by-zero) 43784493Smsmith * 43884493Smsmith * DESCRIPTION: Perform a short (maximum 64 bits divided by 32 bits) 439241973Sjkim * divide and modulo. The result is a 64-bit quotient and a 44084493Smsmith * 32-bit remainder. 44184493Smsmith * 44284493Smsmith ******************************************************************************/ 44384493Smsmith 44484493SmsmithACPI_STATUS 44584493SmsmithAcpiUtShortDivide ( 446202771Sjkim UINT64 Dividend, 44784493Smsmith UINT32 Divisor, 448202771Sjkim UINT64 *OutQuotient, 44984493Smsmith UINT32 *OutRemainder) 45084493Smsmith{ 451138287Smarks UINT64_OVERLAY DividendOvl; 45284493Smsmith UINT64_OVERLAY Quotient; 45384493Smsmith UINT32 Remainder32; 45484493Smsmith 45584493Smsmith 456167802Sjkim ACPI_FUNCTION_TRACE (UtShortDivide); 45784493Smsmith 45884493Smsmith 45984493Smsmith /* Always check for a zero divisor */ 46084493Smsmith 46184493Smsmith if (Divisor == 0) 46284493Smsmith { 463167802Sjkim ACPI_ERROR ((AE_INFO, "Divide by zero")); 46484493Smsmith return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO); 46584493Smsmith } 46684493Smsmith 467138287Smarks DividendOvl.Full = Dividend; 468138287Smarks 46984493Smsmith /* 47084493Smsmith * The quotient is 64 bits, the remainder is always 32 bits, 47184493Smsmith * and is generated by the second divide. 47284493Smsmith */ 473138287Smarks ACPI_DIV_64_BY_32 (0, DividendOvl.Part.Hi, Divisor, 474298714Sjkim Quotient.Part.Hi, Remainder32); 475298714Sjkim 476138287Smarks ACPI_DIV_64_BY_32 (Remainder32, DividendOvl.Part.Lo, Divisor, 477298714Sjkim Quotient.Part.Lo, Remainder32); 47884493Smsmith 47984493Smsmith /* Return only what was requested */ 48084493Smsmith 48184493Smsmith if (OutQuotient) 48284493Smsmith { 48384493Smsmith *OutQuotient = Quotient.Full; 48484493Smsmith } 48584493Smsmith if (OutRemainder) 48684493Smsmith { 48784493Smsmith *OutRemainder = Remainder32; 48884493Smsmith } 48984493Smsmith 49084493Smsmith return_ACPI_STATUS (AE_OK); 49184493Smsmith} 49284493Smsmith 49384493Smsmith 49484493Smsmith/******************************************************************************* 49584493Smsmith * 49684493Smsmith * FUNCTION: AcpiUtDivide 49784493Smsmith * 498138287Smarks * PARAMETERS: InDividend - Dividend 499138287Smarks * InDivisor - Divisor 50084493Smsmith * OutQuotient - Pointer to where the quotient is returned 50184493Smsmith * OutRemainder - Pointer to where the remainder is returned 50284493Smsmith * 50384493Smsmith * RETURN: Status (Checks for divide-by-zero) 50484493Smsmith * 50584493Smsmith * DESCRIPTION: Perform a divide and modulo. 50684493Smsmith * 50784493Smsmith ******************************************************************************/ 50884493Smsmith 50984493SmsmithACPI_STATUS 51084493SmsmithAcpiUtDivide ( 511202771Sjkim UINT64 InDividend, 512202771Sjkim UINT64 InDivisor, 513202771Sjkim UINT64 *OutQuotient, 514202771Sjkim UINT64 *OutRemainder) 51584493Smsmith{ 51684493Smsmith UINT64_OVERLAY Dividend; 51784493Smsmith UINT64_OVERLAY Divisor; 51884493Smsmith UINT64_OVERLAY Quotient; 51984493Smsmith UINT64_OVERLAY Remainder; 52084493Smsmith UINT64_OVERLAY NormalizedDividend; 52184493Smsmith UINT64_OVERLAY NormalizedDivisor; 52284493Smsmith UINT32 Partial1; 52384493Smsmith UINT64_OVERLAY Partial2; 52484493Smsmith UINT64_OVERLAY Partial3; 52584493Smsmith 52684493Smsmith 527167802Sjkim ACPI_FUNCTION_TRACE (UtDivide); 52884493Smsmith 52984493Smsmith 53084493Smsmith /* Always check for a zero divisor */ 53184493Smsmith 532138287Smarks if (InDivisor == 0) 53384493Smsmith { 534167802Sjkim ACPI_ERROR ((AE_INFO, "Divide by zero")); 53584493Smsmith return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO); 53684493Smsmith } 53784493Smsmith 538138287Smarks Divisor.Full = InDivisor; 539138287Smarks Dividend.Full = InDividend; 54084493Smsmith if (Divisor.Part.Hi == 0) 54184493Smsmith { 54284493Smsmith /* 54384493Smsmith * 1) Simplest case is where the divisor is 32 bits, we can 54484493Smsmith * just do two divides 54584493Smsmith */ 54684493Smsmith Remainder.Part.Hi = 0; 54784493Smsmith 54884493Smsmith /* 54984493Smsmith * The quotient is 64 bits, the remainder is always 32 bits, 55084493Smsmith * and is generated by the second divide. 55184493Smsmith */ 55287031Smsmith ACPI_DIV_64_BY_32 (0, Dividend.Part.Hi, Divisor.Part.Lo, 553298714Sjkim Quotient.Part.Hi, Partial1); 554298714Sjkim 55587031Smsmith ACPI_DIV_64_BY_32 (Partial1, Dividend.Part.Lo, Divisor.Part.Lo, 556298714Sjkim Quotient.Part.Lo, Remainder.Part.Lo); 55784493Smsmith } 55884493Smsmith 55984493Smsmith else 56084493Smsmith { 56184493Smsmith /* 56284493Smsmith * 2) The general case where the divisor is a full 64 bits 56384493Smsmith * is more difficult 56484493Smsmith */ 56584493Smsmith Quotient.Part.Hi = 0; 56684493Smsmith NormalizedDividend = Dividend; 56784493Smsmith NormalizedDivisor = Divisor; 56884493Smsmith 56984493Smsmith /* Normalize the operands (shift until the divisor is < 32 bits) */ 57084493Smsmith 57184493Smsmith do 57284493Smsmith { 573298714Sjkim ACPI_SHIFT_RIGHT_64 ( 574298714Sjkim NormalizedDivisor.Part.Hi, NormalizedDivisor.Part.Lo); 575298714Sjkim ACPI_SHIFT_RIGHT_64 ( 576298714Sjkim NormalizedDividend.Part.Hi, NormalizedDividend.Part.Lo); 57784493Smsmith 57884493Smsmith } while (NormalizedDivisor.Part.Hi != 0); 57984493Smsmith 58084493Smsmith /* Partial divide */ 58184493Smsmith 582298714Sjkim ACPI_DIV_64_BY_32 ( 583298714Sjkim NormalizedDividend.Part.Hi, NormalizedDividend.Part.Lo, 584298714Sjkim NormalizedDivisor.Part.Lo, Quotient.Part.Lo, Partial1); 58584493Smsmith 58684493Smsmith /* 587298714Sjkim * The quotient is always 32 bits, and simply requires 588298714Sjkim * adjustment. The 64-bit remainder must be generated. 58984493Smsmith */ 590298714Sjkim Partial1 = Quotient.Part.Lo * Divisor.Part.Hi; 591202771Sjkim Partial2.Full = (UINT64) Quotient.Part.Lo * Divisor.Part.Lo; 592202771Sjkim Partial3.Full = (UINT64) Partial2.Part.Hi + Partial1; 59384493Smsmith 59484493Smsmith Remainder.Part.Hi = Partial3.Part.Lo; 59584493Smsmith Remainder.Part.Lo = Partial2.Part.Lo; 59684493Smsmith 59784493Smsmith if (Partial3.Part.Hi == 0) 59884493Smsmith { 59984493Smsmith if (Partial3.Part.Lo >= Dividend.Part.Hi) 60084493Smsmith { 60184493Smsmith if (Partial3.Part.Lo == Dividend.Part.Hi) 60284493Smsmith { 60384493Smsmith if (Partial2.Part.Lo > Dividend.Part.Lo) 60484493Smsmith { 60584493Smsmith Quotient.Part.Lo--; 60684493Smsmith Remainder.Full -= Divisor.Full; 60784493Smsmith } 60884493Smsmith } 60984493Smsmith else 61084493Smsmith { 61184493Smsmith Quotient.Part.Lo--; 61284493Smsmith Remainder.Full -= Divisor.Full; 61384493Smsmith } 61484493Smsmith } 61584493Smsmith 616298714Sjkim Remainder.Full = Remainder.Full - Dividend.Full; 61799679Siwasaki Remainder.Part.Hi = (UINT32) -((INT32) Remainder.Part.Hi); 61899679Siwasaki Remainder.Part.Lo = (UINT32) -((INT32) Remainder.Part.Lo); 61984493Smsmith 62084493Smsmith if (Remainder.Part.Lo) 62184493Smsmith { 62284493Smsmith Remainder.Part.Hi--; 62384493Smsmith } 62484493Smsmith } 62584493Smsmith } 62684493Smsmith 62784493Smsmith /* Return only what was requested */ 62884493Smsmith 62984493Smsmith if (OutQuotient) 63084493Smsmith { 63184493Smsmith *OutQuotient = Quotient.Full; 63284493Smsmith } 63384493Smsmith if (OutRemainder) 63484493Smsmith { 63584493Smsmith *OutRemainder = Remainder.Full; 63684493Smsmith } 63784493Smsmith 63884493Smsmith return_ACPI_STATUS (AE_OK); 63984493Smsmith} 64084493Smsmith 64184493Smsmith#else 64284493Smsmith 64384493Smsmith/******************************************************************************* 64484493Smsmith * 64584493Smsmith * FUNCTION: AcpiUtShortDivide, AcpiUtDivide 64684493Smsmith * 647151937Sjkim * PARAMETERS: See function headers above 648151937Sjkim * 64984493Smsmith * DESCRIPTION: Native versions of the UtDivide functions. Use these if either 65084493Smsmith * 1) The target is a 64-bit platform and therefore 64-bit 65184493Smsmith * integer math is supported directly by the machine. 65287031Smsmith * 2) The target is a 32-bit or 16-bit platform, and the 65387031Smsmith * double-precision integer math library is available to 65484493Smsmith * perform the divide. 65584493Smsmith * 65684493Smsmith ******************************************************************************/ 65784493Smsmith 65884493SmsmithACPI_STATUS 65984493SmsmithAcpiUtShortDivide ( 660202771Sjkim UINT64 InDividend, 66184493Smsmith UINT32 Divisor, 662202771Sjkim UINT64 *OutQuotient, 66384493Smsmith UINT32 *OutRemainder) 66484493Smsmith{ 66584493Smsmith 666167802Sjkim ACPI_FUNCTION_TRACE (UtShortDivide); 66784493Smsmith 66884493Smsmith 66984493Smsmith /* Always check for a zero divisor */ 67084493Smsmith 67184493Smsmith if (Divisor == 0) 67284493Smsmith { 673167802Sjkim ACPI_ERROR ((AE_INFO, "Divide by zero")); 67484493Smsmith return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO); 67584493Smsmith } 67684493Smsmith 67784493Smsmith /* Return only what was requested */ 67884493Smsmith 67984493Smsmith if (OutQuotient) 68084493Smsmith { 681138287Smarks *OutQuotient = InDividend / Divisor; 68284493Smsmith } 68384493Smsmith if (OutRemainder) 68484493Smsmith { 685193267Sjkim *OutRemainder = (UINT32) (InDividend % Divisor); 68684493Smsmith } 68784493Smsmith 68884493Smsmith return_ACPI_STATUS (AE_OK); 68984493Smsmith} 69084493Smsmith 69184493SmsmithACPI_STATUS 69284493SmsmithAcpiUtDivide ( 693202771Sjkim UINT64 InDividend, 694202771Sjkim UINT64 InDivisor, 695202771Sjkim UINT64 *OutQuotient, 696202771Sjkim UINT64 *OutRemainder) 69784493Smsmith{ 698167802Sjkim ACPI_FUNCTION_TRACE (UtDivide); 69984493Smsmith 70084493Smsmith 70184493Smsmith /* Always check for a zero divisor */ 70284493Smsmith 703138287Smarks if (InDivisor == 0) 70484493Smsmith { 705167802Sjkim ACPI_ERROR ((AE_INFO, "Divide by zero")); 70684493Smsmith return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO); 70784493Smsmith } 70884493Smsmith 70984493Smsmith 71084493Smsmith /* Return only what was requested */ 71184493Smsmith 71284493Smsmith if (OutQuotient) 71384493Smsmith { 714138287Smarks *OutQuotient = InDividend / InDivisor; 71584493Smsmith } 71684493Smsmith if (OutRemainder) 71784493Smsmith { 718138287Smarks *OutRemainder = InDividend % InDivisor; 71984493Smsmith } 72084493Smsmith 72185756Smsmith return_ACPI_STATUS (AE_OK); 72284493Smsmith} 72384493Smsmith 72484493Smsmith#endif 725