Home | History | Annotate | Line # | Download | only in utilities
      1 /*******************************************************************************
      2  *
      3  * Module Name: utstrsuppt - Support functions for string-to-integer conversion
      4  *
      5  ******************************************************************************/
      6 
      7 /******************************************************************************
      8  *
      9  * 1. Copyright Notice
     10  *
     11  * Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.
     12  * All rights reserved.
     13  *
     14  * 2. License
     15  *
     16  * 2.1. This is your license from Intel Corp. under its intellectual property
     17  * rights. You may have additional license terms from the party that provided
     18  * you this software, covering your right to use that party's intellectual
     19  * property rights.
     20  *
     21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
     22  * copy of the source code appearing in this file ("Covered Code") an
     23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
     24  * base code distributed originally by Intel ("Original Intel Code") to copy,
     25  * make derivatives, distribute, use and display any portion of the Covered
     26  * Code in any form, with the right to sublicense such rights; and
     27  *
     28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
     29  * license (with the right to sublicense), under only those claims of Intel
     30  * patents that are infringed by the Original Intel Code, to make, use, sell,
     31  * offer to sell, and import the Covered Code and derivative works thereof
     32  * solely to the minimum extent necessary to exercise the above copyright
     33  * license, and in no event shall the patent license extend to any additions
     34  * to or modifications of the Original Intel Code. No other license or right
     35  * is granted directly or by implication, estoppel or otherwise;
     36  *
     37  * The above copyright and patent license is granted only if the following
     38  * conditions are met:
     39  *
     40  * 3. Conditions
     41  *
     42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
     43  * Redistribution of source code of any substantial portion of the Covered
     44  * Code or modification with rights to further distribute source must include
     45  * the above Copyright Notice, the above License, this list of Conditions,
     46  * and the following Disclaimer and Export Compliance provision. In addition,
     47  * Licensee must cause all Covered Code to which Licensee contributes to
     48  * contain a file documenting the changes Licensee made to create that Covered
     49  * Code and the date of any change. Licensee must include in that file the
     50  * documentation of any changes made by any predecessor Licensee. Licensee
     51  * must include a prominent statement that the modification is derived,
     52  * directly or indirectly, from Original Intel Code.
     53  *
     54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
     55  * Redistribution of source code of any substantial portion of the Covered
     56  * Code or modification without rights to further distribute source must
     57  * include the following Disclaimer and Export Compliance provision in the
     58  * documentation and/or other materials provided with distribution. In
     59  * addition, Licensee may not authorize further sublicense of source of any
     60  * portion of the Covered Code, and must include terms to the effect that the
     61  * license from Licensee to its licensee is limited to the intellectual
     62  * property embodied in the software Licensee provides to its licensee, and
     63  * not to intellectual property embodied in modifications its licensee may
     64  * make.
     65  *
     66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
     67  * substantial portion of the Covered Code or modification must reproduce the
     68  * above Copyright Notice, and the following Disclaimer and Export Compliance
     69  * provision in the documentation and/or other materials provided with the
     70  * distribution.
     71  *
     72  * 3.4. Intel retains all right, title, and interest in and to the Original
     73  * Intel Code.
     74  *
     75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
     76  * Intel shall be used in advertising or otherwise to promote the sale, use or
     77  * other dealings in products derived from or relating to the Covered Code
     78  * without prior written authorization from Intel.
     79  *
     80  * 4. Disclaimer and Export Compliance
     81  *
     82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
     83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
     84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
     85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
     86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
     87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
     88  * PARTICULAR PURPOSE.
     89  *
     90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
     91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
     92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
     93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
     94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
     95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
     96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
     97  * LIMITED REMEDY.
     98  *
     99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
    100  * software or system incorporating such software without first obtaining any
    101  * required license or other approval from the U. S. Department of Commerce or
    102  * any other agency or department of the United States Government. In the
    103  * event Licensee exports any such software from the United States or
    104  * re-exports any such software from a foreign destination, Licensee shall
    105  * ensure that the distribution and export/re-export of the software is in
    106  * compliance with all laws, regulations, orders, or other restrictions of the
    107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
    108  * any of its subsidiaries will export/re-export any technical data, process,
    109  * software, or service, directly or indirectly, to any country for which the
    110  * United States government or any agency thereof requires an export license,
    111  * other governmental approval, or letter of assurance, without first obtaining
    112  * such license, approval or letter.
    113  *
    114  *****************************************************************************
    115  *
    116  * Alternatively, you may choose to be licensed under the terms of the
    117  * following license:
    118  *
    119  * Redistribution and use in source and binary forms, with or without
    120  * modification, are permitted provided that the following conditions
    121  * are met:
    122  * 1. Redistributions of source code must retain the above copyright
    123  *    notice, this list of conditions, and the following disclaimer,
    124  *    without modification.
    125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
    126  *    substantially similar to the "NO WARRANTY" disclaimer below
    127  *    ("Disclaimer") and any redistribution must be conditioned upon
    128  *    including a substantially similar Disclaimer requirement for further
    129  *    binary redistribution.
    130  * 3. Neither the names of the above-listed copyright holders nor the names
    131  *    of any contributors may be used to endorse or promote products derived
    132  *    from this software without specific prior written permission.
    133  *
    134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    145  *
    146  * Alternatively, you may choose to be licensed under the terms of the
    147  * GNU General Public License ("GPL") version 2 as published by the Free
    148  * Software Foundation.
    149  *
    150  *****************************************************************************/
    151 
    152 #include "acpi.h"
    153 #include "accommon.h"
    154 
    155 #define _COMPONENT          ACPI_UTILITIES
    156         ACPI_MODULE_NAME    ("utstrsuppt")
    157 
    158 
    159 /* Local prototypes */
    160 
    161 static ACPI_STATUS
    162 AcpiUtInsertDigit (
    163     UINT64                  *AccumulatedValue,
    164     UINT32                  Base,
    165     int                     AsciiDigit);
    166 
    167 static ACPI_STATUS
    168 AcpiUtStrtoulMultiply64 (
    169     UINT64                  Multiplicand,
    170     UINT32                  Base,
    171     UINT64                  *OutProduct);
    172 
    173 static ACPI_STATUS
    174 AcpiUtStrtoulAdd64 (
    175     UINT64                  Addend1,
    176     UINT32                  Digit,
    177     UINT64                  *OutSum);
    178 
    179 
    180 /*******************************************************************************
    181  *
    182  * FUNCTION:    AcpiUtConvertOctalString
    183  *
    184  * PARAMETERS:  String                  - Null terminated input string
    185  *              ReturnValuePtr          - Where the converted value is returned
    186  *
    187  * RETURN:      Status and 64-bit converted integer
    188  *
    189  * DESCRIPTION: Performs a base 8 conversion of the input string to an
    190  *              integer value, either 32 or 64 bits.
    191  *
    192  * NOTE:        Maximum 64-bit unsigned octal value is 01777777777777777777777
    193  *              Maximum 32-bit unsigned octal value is 037777777777
    194  *
    195  ******************************************************************************/
    196 
    197 ACPI_STATUS
    198 AcpiUtConvertOctalString (
    199     char                    *String,
    200     UINT64                  *ReturnValuePtr)
    201 {
    202     UINT64                  AccumulatedValue = 0;
    203     ACPI_STATUS             Status = AE_OK;
    204 
    205 
    206     /* Convert each ASCII byte in the input string */
    207 
    208     while (*String)
    209     {
    210         /*
    211          * Character must be ASCII 0-7, otherwise:
    212          * 1) Runtime: terminate with no error, per the ACPI spec
    213          * 2) Compiler: return an error
    214          */
    215         if (!(ACPI_IS_OCTAL_DIGIT (*String)))
    216         {
    217 #ifdef ACPI_ASL_COMPILER
    218             Status = AE_BAD_OCTAL_CONSTANT;
    219 #endif
    220             break;
    221         }
    222 
    223         /* Convert and insert this octal digit into the accumulator */
    224 
    225         Status = AcpiUtInsertDigit (&AccumulatedValue, 8, *String);
    226         if (ACPI_FAILURE (Status))
    227         {
    228             Status = AE_OCTAL_OVERFLOW;
    229             break;
    230         }
    231 
    232         String++;
    233     }
    234 
    235     /* Always return the value that has been accumulated */
    236 
    237     *ReturnValuePtr = AccumulatedValue;
    238     return (Status);
    239 }
    240 
    241 
    242 /*******************************************************************************
    243  *
    244  * FUNCTION:    AcpiUtConvertDecimalString
    245  *
    246  * PARAMETERS:  String                  - Null terminated input string
    247  *              ReturnValuePtr          - Where the converted value is returned
    248  *
    249  * RETURN:      Status and 64-bit converted integer
    250  *
    251  * DESCRIPTION: Performs a base 10 conversion of the input string to an
    252  *              integer value, either 32 or 64 bits.
    253  *
    254  * NOTE:        Maximum 64-bit unsigned decimal value is 18446744073709551615
    255  *              Maximum 32-bit unsigned decimal value is 4294967295
    256  *
    257  ******************************************************************************/
    258 
    259 ACPI_STATUS
    260 AcpiUtConvertDecimalString (
    261     char                    *String,
    262     UINT64                  *ReturnValuePtr)
    263 {
    264     UINT64                  AccumulatedValue = 0;
    265     ACPI_STATUS             Status = AE_OK;
    266 
    267 
    268     /* Convert each ASCII byte in the input string */
    269 
    270     while (*String)
    271     {
    272         /*
    273          * Character must be ASCII 0-9, otherwise:
    274          * 1) Runtime: terminate with no error, per the ACPI spec
    275          * 2) Compiler: return an error
    276          */
    277         if (!isdigit ((int) *String))
    278         {
    279 #ifdef ACPI_ASL_COMPILER
    280             Status = AE_BAD_DECIMAL_CONSTANT;
    281 #endif
    282            break;
    283         }
    284 
    285         /* Convert and insert this decimal digit into the accumulator */
    286 
    287         Status = AcpiUtInsertDigit (&AccumulatedValue, 10, *String);
    288         if (ACPI_FAILURE (Status))
    289         {
    290             Status = AE_DECIMAL_OVERFLOW;
    291             break;
    292         }
    293 
    294         String++;
    295     }
    296 
    297     /* Always return the value that has been accumulated */
    298 
    299     *ReturnValuePtr = AccumulatedValue;
    300     return (Status);
    301 }
    302 
    303 
    304 /*******************************************************************************
    305  *
    306  * FUNCTION:    AcpiUtConvertHexString
    307  *
    308  * PARAMETERS:  String                  - Null terminated input string
    309  *              ReturnValuePtr          - Where the converted value is returned
    310  *
    311  * RETURN:      Status and 64-bit converted integer
    312  *
    313  * DESCRIPTION: Performs a base 16 conversion of the input string to an
    314  *              integer value, either 32 or 64 bits.
    315  *
    316  * NOTE:        Maximum 64-bit unsigned hex value is 0xFFFFFFFFFFFFFFFF
    317  *              Maximum 32-bit unsigned hex value is 0xFFFFFFFF
    318  *
    319  ******************************************************************************/
    320 
    321 ACPI_STATUS
    322 AcpiUtConvertHexString (
    323     char                    *String,
    324     UINT64                  *ReturnValuePtr)
    325 {
    326     UINT64                  AccumulatedValue = 0;
    327     ACPI_STATUS             Status = AE_OK;
    328 
    329 
    330     /* Convert each ASCII byte in the input string */
    331 
    332     while (*String)
    333     {
    334         /*
    335          * Character must be ASCII A-F, a-f, or 0-9, otherwise:
    336          * 1) Runtime: terminate with no error, per the ACPI spec
    337          * 2) Compiler: return an error
    338          */
    339         if (!isxdigit ((int) *String))
    340         {
    341 #ifdef ACPI_ASL_COMPILER
    342             Status = AE_BAD_HEX_CONSTANT;
    343 #endif
    344             break;
    345         }
    346 
    347         /* Convert and insert this hex digit into the accumulator */
    348 
    349         Status = AcpiUtInsertDigit (&AccumulatedValue, 16, *String);
    350         if (ACPI_FAILURE (Status))
    351         {
    352             Status = AE_HEX_OVERFLOW;
    353             break;
    354         }
    355 
    356         String++;
    357     }
    358 
    359     /* Always return the value that has been accumulated */
    360 
    361     *ReturnValuePtr = AccumulatedValue;
    362     return (Status);
    363 }
    364 
    365 
    366 /*******************************************************************************
    367  *
    368  * FUNCTION:    AcpiUtRemoveLeadingZeros
    369  *
    370  * PARAMETERS:  String                  - Pointer to input ASCII string
    371  *
    372  * RETURN:      Next character after any leading zeros. This character may be
    373  *              used by the caller to detect end-of-string.
    374  *
    375  * DESCRIPTION: Remove any leading zeros in the input string. Return the
    376  *              next character after the final ASCII zero to enable the caller
    377  *              to check for the end of the string (NULL terminator).
    378  *
    379  ******************************************************************************/
    380 
    381 char
    382 AcpiUtRemoveLeadingZeros (
    383     char                    **String)
    384 {
    385 
    386     while (**String == ACPI_ASCII_ZERO)
    387     {
    388         *String += 1;
    389     }
    390 
    391     return (**String);
    392 }
    393 
    394 
    395 /*******************************************************************************
    396  *
    397  * FUNCTION:    AcpiUtRemoveWhitespace
    398  *
    399  * PARAMETERS:  String                  - Pointer to input ASCII string
    400  *
    401  * RETURN:      Next character after any whitespace. This character may be
    402  *              used by the caller to detect end-of-string.
    403  *
    404  * DESCRIPTION: Remove any leading whitespace in the input string. Return the
    405  *              next character after the final ASCII zero to enable the caller
    406  *              to check for the end of the string (NULL terminator).
    407  *
    408  ******************************************************************************/
    409 
    410 char
    411 AcpiUtRemoveWhitespace (
    412     char                    **String)
    413 {
    414 
    415     while (isspace ((UINT8) **String))
    416     {
    417         *String += 1;
    418     }
    419 
    420     return (**String);
    421 }
    422 
    423 
    424 /*******************************************************************************
    425  *
    426  * FUNCTION:    AcpiUtDetectHexPrefix
    427  *
    428  * PARAMETERS:  String                  - Pointer to input ASCII string
    429  *
    430  * RETURN:      TRUE if a "0x" prefix was found at the start of the string
    431  *
    432  * DESCRIPTION: Detect and remove a hex "0x" prefix
    433  *
    434  ******************************************************************************/
    435 
    436 BOOLEAN
    437 AcpiUtDetectHexPrefix (
    438     char                    **String)
    439 {
    440     char                    *InitialPosition = *String;
    441 
    442     AcpiUtRemoveHexPrefix (String);
    443     if (*String != InitialPosition)
    444     {
    445         return (TRUE); /* String is past leading 0x */
    446     }
    447 
    448     return (FALSE);     /* Not a hex string */
    449 }
    450 
    451 
    452 /*******************************************************************************
    453  *
    454  * FUNCTION:    AcpiUtRemoveHexPrefix
    455  *
    456  * PARAMETERS:  String                  - Pointer to input ASCII string
    457  *
    458  * RETURN:      none
    459  *
    460  * DESCRIPTION: Remove a hex "0x" prefix
    461  *
    462  ******************************************************************************/
    463 
    464 void
    465 AcpiUtRemoveHexPrefix (
    466     char                    **String)
    467 {
    468     if ((**String == ACPI_ASCII_ZERO) &&
    469         (tolower ((int) *(*String + 1)) == 'x'))
    470     {
    471         *String += 2;        /* Go past the leading 0x */
    472     }
    473 }
    474 
    475 
    476 /*******************************************************************************
    477  *
    478  * FUNCTION:    AcpiUtDetectOctalPrefix
    479  *
    480  * PARAMETERS:  String                  - Pointer to input ASCII string
    481  *
    482  * RETURN:      True if an octal "0" prefix was found at the start of the
    483  *              string
    484  *
    485  * DESCRIPTION: Detect and remove an octal prefix (zero)
    486  *
    487  ******************************************************************************/
    488 
    489 BOOLEAN
    490 AcpiUtDetectOctalPrefix (
    491     char                    **String)
    492 {
    493 
    494     if (**String == ACPI_ASCII_ZERO)
    495     {
    496         *String += 1;       /* Go past the leading 0 */
    497         return (TRUE);
    498     }
    499 
    500     return (FALSE);     /* Not an octal string */
    501 }
    502 
    503 
    504 /*******************************************************************************
    505  *
    506  * FUNCTION:    AcpiUtInsertDigit
    507  *
    508  * PARAMETERS:  AccumulatedValue        - Current value of the integer value
    509  *                                        accumulator. The new value is
    510  *                                        returned here.
    511  *              Base                    - Radix, either 8/10/16
    512  *              AsciiDigit              - ASCII single digit to be inserted
    513  *
    514  * RETURN:      Status and result of the convert/insert operation. The only
    515  *              possible returned exception code is numeric overflow of
    516  *              either the multiply or add conversion operations.
    517  *
    518  * DESCRIPTION: Generic conversion and insertion function for all bases:
    519  *
    520  *              1) Multiply the current accumulated/converted value by the
    521  *              base in order to make room for the new character.
    522  *
    523  *              2) Convert the new character to binary and add it to the
    524  *              current accumulated value.
    525  *
    526  *              Note: The only possible exception indicates an integer
    527  *              overflow (AE_NUMERIC_OVERFLOW)
    528  *
    529  ******************************************************************************/
    530 
    531 static ACPI_STATUS
    532 AcpiUtInsertDigit (
    533     UINT64                  *AccumulatedValue,
    534     UINT32                  Base,
    535     int                     AsciiDigit)
    536 {
    537     ACPI_STATUS             Status;
    538     UINT64                  Product;
    539 
    540 
    541      /* Make room in the accumulated value for the incoming digit */
    542 
    543     Status = AcpiUtStrtoulMultiply64 (*AccumulatedValue, Base, &Product);
    544     if (ACPI_FAILURE (Status))
    545     {
    546         return (Status);
    547     }
    548 
    549     /* Add in the new digit, and store the sum to the accumulated value */
    550 
    551     Status = AcpiUtStrtoulAdd64 (Product, AcpiUtAsciiCharToHex (AsciiDigit),
    552         AccumulatedValue);
    553 
    554     return (Status);
    555 }
    556 
    557 
    558 /*******************************************************************************
    559  *
    560  * FUNCTION:    AcpiUtStrtoulMultiply64
    561  *
    562  * PARAMETERS:  Multiplicand            - Current accumulated converted integer
    563  *              Base                    - Base/Radix
    564  *              OutProduct              - Where the product is returned
    565  *
    566  * RETURN:      Status and 64-bit product
    567  *
    568  * DESCRIPTION: Multiply two 64-bit values, with checking for 64-bit overflow as
    569  *              well as 32-bit overflow if necessary (if the current global
    570  *              integer width is 32).
    571  *
    572  ******************************************************************************/
    573 
    574 static ACPI_STATUS
    575 AcpiUtStrtoulMultiply64 (
    576     UINT64                  Multiplicand,
    577     UINT32                  Base,
    578     UINT64                  *OutProduct)
    579 {
    580     UINT64                  Product;
    581     UINT64                  Quotient;
    582 
    583 
    584     /* Exit if either operand is zero */
    585 
    586     *OutProduct = 0;
    587     if (!Multiplicand || !Base)
    588     {
    589         return (AE_OK);
    590     }
    591 
    592     /*
    593      * Check for 64-bit overflow before the actual multiplication.
    594      *
    595      * Notes: 64-bit division is often not supported on 32-bit platforms
    596      * (it requires a library function), Therefore ACPICA has a local
    597      * 64-bit divide function. Also, Multiplier is currently only used
    598      * as the radix (8/10/16), to the 64/32 divide will always work.
    599      */
    600     AcpiUtShortDivide (ACPI_UINT64_MAX, Base, &Quotient, NULL);
    601     if (Multiplicand > Quotient)
    602     {
    603         return (AE_NUMERIC_OVERFLOW);
    604     }
    605 
    606     Product = Multiplicand * Base;
    607 
    608     /* Check for 32-bit overflow if necessary */
    609 
    610     if ((AcpiGbl_IntegerBitWidth == 32) && (Product > ACPI_UINT32_MAX))
    611     {
    612         return (AE_NUMERIC_OVERFLOW);
    613     }
    614 
    615     *OutProduct = Product;
    616     return (AE_OK);
    617 }
    618 
    619 
    620 /*******************************************************************************
    621  *
    622  * FUNCTION:    AcpiUtStrtoulAdd64
    623  *
    624  * PARAMETERS:  Addend1                 - Current accumulated converted integer
    625  *              Digit                   - New hex value/char
    626  *              OutSum                  - Where sum is returned (Accumulator)
    627  *
    628  * RETURN:      Status and 64-bit sum
    629  *
    630  * DESCRIPTION: Add two 64-bit values, with checking for 64-bit overflow as
    631  *              well as 32-bit overflow if necessary (if the current global
    632  *              integer width is 32).
    633  *
    634  ******************************************************************************/
    635 
    636 static ACPI_STATUS
    637 AcpiUtStrtoulAdd64 (
    638     UINT64                  Addend1,
    639     UINT32                  Digit,
    640     UINT64                  *OutSum)
    641 {
    642     UINT64                  Sum;
    643 
    644 
    645     /* Check for 64-bit overflow before the actual addition */
    646 
    647     if ((Addend1 > 0) && (Digit > (ACPI_UINT64_MAX - Addend1)))
    648     {
    649         return (AE_NUMERIC_OVERFLOW);
    650     }
    651 
    652     Sum = Addend1 + Digit;
    653 
    654     /* Check for 32-bit overflow if necessary */
    655 
    656     if ((AcpiGbl_IntegerBitWidth == 32) && (Sum > ACPI_UINT32_MAX))
    657     {
    658         return (AE_NUMERIC_OVERFLOW);
    659     }
    660 
    661     *OutSum = Sum;
    662     return (AE_OK);
    663 }
    664