Subversion Repositories Kolibri OS

Rev

Rev 1498 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1498 Rev 2216
1
/*******************************************************************************
1
/*******************************************************************************
2
 *
2
 *
3
 * Module Name: utmath - Integer math support routines
3
 * Module Name: utmath - Integer math support routines
4
 *
4
 *
5
 ******************************************************************************/
5
 ******************************************************************************/
6
 
6
 
7
/******************************************************************************
7
/******************************************************************************
8
 *
8
 *
9
 * 1. Copyright Notice
9
 * 1. Copyright Notice
10
 *
10
 *
11
 * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
11
 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
12
 * All rights reserved.
12
 * All rights reserved.
13
 *
13
 *
14
 * 2. License
14
 * 2. License
15
 *
15
 *
16
 * 2.1. This is your license from Intel Corp. under its intellectual property
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
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
18
 * you this software, covering your right to use that party's intellectual
19
 * property rights.
19
 * property rights.
20
 *
20
 *
21
 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
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
22
 * copy of the source code appearing in this file ("Covered Code") an
23
 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
23
 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24
 * base code distributed originally by Intel ("Original Intel Code") to copy,
24
 * base code distributed originally by Intel ("Original Intel Code") to copy,
25
 * make derivatives, distribute, use and display any portion of the Covered
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
26
 * Code in any form, with the right to sublicense such rights; and
27
 *
27
 *
28
 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
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
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,
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
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
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
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
34
 * to or modifications of the Original Intel Code.  No other license or right
35
 * is granted directly or by implication, estoppel or otherwise;
35
 * is granted directly or by implication, estoppel or otherwise;
36
 *
36
 *
37
 * The above copyright and patent license is granted only if the following
37
 * The above copyright and patent license is granted only if the following
38
 * conditions are met:
38
 * conditions are met:
39
 *
39
 *
40
 * 3. Conditions
40
 * 3. Conditions
41
 *
41
 *
42
 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
42
 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43
 * Redistribution of source code of any substantial portion of the Covered
43
 * Redistribution of source code of any substantial portion of the Covered
44
 * Code or modification with rights to further distribute source must include
44
 * Code or modification with rights to further distribute source must include
45
 * the above Copyright Notice, the above License, this list of Conditions,
45
 * the above Copyright Notice, the above License, this list of Conditions,
46
 * and the following Disclaimer and Export Compliance provision.  In addition,
46
 * and the following Disclaimer and Export Compliance provision.  In addition,
47
 * Licensee must cause all Covered Code to which Licensee contributes to
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
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
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
50
 * documentation of any changes made by any predecessor Licensee.  Licensee
51
 * must include a prominent statement that the modification is derived,
51
 * must include a prominent statement that the modification is derived,
52
 * directly or indirectly, from Original Intel Code.
52
 * directly or indirectly, from Original Intel Code.
53
 *
53
 *
54
 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
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
55
 * Redistribution of source code of any substantial portion of the Covered
56
 * Code or modification without rights to further distribute source must
56
 * Code or modification without rights to further distribute source must
57
 * include the following Disclaimer and Export Compliance provision in the
57
 * include the following Disclaimer and Export Compliance provision in the
58
 * documentation and/or other materials provided with distribution.  In
58
 * documentation and/or other materials provided with distribution.  In
59
 * addition, Licensee may not authorize further sublicense of source of any
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
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
61
 * license from Licensee to its licensee is limited to the intellectual
62
 * property embodied in the software Licensee provides to its licensee, and
62
 * property embodied in the software Licensee provides to its licensee, and
63
 * not to intellectual property embodied in modifications its licensee may
63
 * not to intellectual property embodied in modifications its licensee may
64
 * make.
64
 * make.
65
 *
65
 *
66
 * 3.3. Redistribution of Executable. Redistribution in executable form of any
66
 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67
 * substantial portion of the Covered Code or modification must reproduce the
67
 * substantial portion of the Covered Code or modification must reproduce the
68
 * above Copyright Notice, and the following Disclaimer and Export Compliance
68
 * above Copyright Notice, and the following Disclaimer and Export Compliance
69
 * provision in the documentation and/or other materials provided with the
69
 * provision in the documentation and/or other materials provided with the
70
 * distribution.
70
 * distribution.
71
 *
71
 *
72
 * 3.4. Intel retains all right, title, and interest in and to the Original
72
 * 3.4. Intel retains all right, title, and interest in and to the Original
73
 * Intel Code.
73
 * Intel Code.
74
 *
74
 *
75
 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
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
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
77
 * other dealings in products derived from or relating to the Covered Code
78
 * without prior written authorization from Intel.
78
 * without prior written authorization from Intel.
79
 *
79
 *
80
 * 4. Disclaimer and Export Compliance
80
 * 4. Disclaimer and Export Compliance
81
 *
81
 *
82
 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
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
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,
84
 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85
 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
85
 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86
 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
86
 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87
 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
87
 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88
 * PARTICULAR PURPOSE.
88
 * PARTICULAR PURPOSE.
89
 *
89
 *
90
 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
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
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,
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
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
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
95
 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96
 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
96
 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97
 * LIMITED REMEDY.
97
 * LIMITED REMEDY.
98
 *
98
 *
99
 * 4.3. Licensee shall not export, either directly or indirectly, any of this
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
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
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
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
103
 * event Licensee exports any such software from the United States or
104
 * re-exports any such software from a foreign destination, Licensee shall
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
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
106
 * compliance with all laws, regulations, orders, or other restrictions of the
107
 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
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,
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
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,
110
 * United States government or any agency thereof requires an export license,
111
 * other governmental approval, or letter of assurance, without first obtaining
111
 * other governmental approval, or letter of assurance, without first obtaining
112
 * such license, approval or letter.
112
 * such license, approval or letter.
113
 *
113
 *
114
 *****************************************************************************/
114
 *****************************************************************************/
115
 
115
 
116
 
116
 
117
#define __UTMATH_C__
117
#define __UTMATH_C__
118
 
118
 
119
#include "acpi.h"
119
#include "acpi.h"
120
#include "accommon.h"
120
#include "accommon.h"
121
 
121
 
122
 
122
 
123
#define _COMPONENT          ACPI_UTILITIES
123
#define _COMPONENT          ACPI_UTILITIES
124
        ACPI_MODULE_NAME    ("utmath")
124
        ACPI_MODULE_NAME    ("utmath")
125
 
125
 
126
/*
126
/*
127
 * Support for double-precision integer divide.  This code is included here
127
 * Optional support for 64-bit double-precision integer divide. This code
128
 * in order to support kernel environments where the double-precision math
128
 * is configurable and is implemented in order to support 32-bit kernel
129
 * library is not available.
129
 * environments where a 64-bit double-precision math library is not available.
-
 
130
 *
-
 
131
 * Support for a more normal 64-bit divide/modulo (with check for a divide-
-
 
132
 * by-zero) appears after this optional section of code.
130
 */
133
 */
131
 
-
 
132
#ifndef ACPI_USE_NATIVE_DIVIDE
134
#ifndef ACPI_USE_NATIVE_DIVIDE
-
 
135
 
-
 
136
/* Structures used only for 64-bit divide */
-
 
137
 
-
 
138
typedef struct uint64_struct
-
 
139
{
-
 
140
    UINT32                          Lo;
-
 
141
    UINT32                          Hi;
-
 
142
 
-
 
143
} UINT64_STRUCT;
-
 
144
 
-
 
145
typedef union uint64_overlay
-
 
146
{
-
 
147
    UINT64                          Full;
-
 
148
    UINT64_STRUCT                   Part;
-
 
149
 
-
 
150
} UINT64_OVERLAY;
-
 
151
 
-
 
152
 
133
/*******************************************************************************
153
/*******************************************************************************
134
 *
154
 *
135
 * FUNCTION:    AcpiUtShortDivide
155
 * FUNCTION:    AcpiUtShortDivide
136
 *
156
 *
137
 * PARAMETERS:  Dividend            - 64-bit dividend
157
 * PARAMETERS:  Dividend            - 64-bit dividend
138
 *              Divisor             - 32-bit divisor
158
 *              Divisor             - 32-bit divisor
139
 *              OutQuotient         - Pointer to where the quotient is returned
159
 *              OutQuotient         - Pointer to where the quotient is returned
140
 *              OutRemainder        - Pointer to where the remainder is returned
160
 *              OutRemainder        - Pointer to where the remainder is returned
141
 *
161
 *
142
 * RETURN:      Status (Checks for divide-by-zero)
162
 * RETURN:      Status (Checks for divide-by-zero)
143
 *
163
 *
144
 * DESCRIPTION: Perform a short (maximum 64 bits divided by 32 bits)
164
 * DESCRIPTION: Perform a short (maximum 64 bits divided by 32 bits)
145
 *              divide and modulo.  The result is a 64-bit quotient and a
165
 *              divide and modulo.  The result is a 64-bit quotient and a
146
 *              32-bit remainder.
166
 *              32-bit remainder.
147
 *
167
 *
148
 ******************************************************************************/
168
 ******************************************************************************/
149
 
169
 
150
ACPI_STATUS
170
ACPI_STATUS
151
AcpiUtShortDivide (
171
AcpiUtShortDivide (
152
    UINT64                  Dividend,
172
    UINT64                  Dividend,
153
    UINT32                  Divisor,
173
    UINT32                  Divisor,
154
    UINT64                  *OutQuotient,
174
    UINT64                  *OutQuotient,
155
    UINT32                  *OutRemainder)
175
    UINT32                  *OutRemainder)
156
{
176
{
157
    UINT64_OVERLAY          DividendOvl;
177
    UINT64_OVERLAY          DividendOvl;
158
    UINT64_OVERLAY          Quotient;
178
    UINT64_OVERLAY          Quotient;
159
    UINT32                  Remainder32;
179
    UINT32                  Remainder32;
160
 
180
 
161
 
181
 
162
    ACPI_FUNCTION_TRACE (UtShortDivide);
182
    ACPI_FUNCTION_TRACE (UtShortDivide);
163
 
183
 
164
 
184
 
165
    /* Always check for a zero divisor */
185
    /* Always check for a zero divisor */
166
 
186
 
167
    if (Divisor == 0)
187
    if (Divisor == 0)
168
    {
188
    {
169
        ACPI_ERROR ((AE_INFO, "Divide by zero"));
189
        ACPI_ERROR ((AE_INFO, "Divide by zero"));
170
        return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
190
        return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
171
    }
191
    }
172
 
192
 
173
    DividendOvl.Full = Dividend;
193
    DividendOvl.Full = Dividend;
174
 
194
 
175
    /*
195
    /*
176
     * The quotient is 64 bits, the remainder is always 32 bits,
196
     * The quotient is 64 bits, the remainder is always 32 bits,
177
     * and is generated by the second divide.
197
     * and is generated by the second divide.
178
     */
198
     */
179
    ACPI_DIV_64_BY_32 (0, DividendOvl.Part.Hi, Divisor,
199
    ACPI_DIV_64_BY_32 (0, DividendOvl.Part.Hi, Divisor,
180
                       Quotient.Part.Hi, Remainder32);
200
                       Quotient.Part.Hi, Remainder32);
181
    ACPI_DIV_64_BY_32 (Remainder32, DividendOvl.Part.Lo, Divisor,
201
    ACPI_DIV_64_BY_32 (Remainder32, DividendOvl.Part.Lo, Divisor,
182
                       Quotient.Part.Lo, Remainder32);
202
                       Quotient.Part.Lo, Remainder32);
183
 
203
 
184
    /* Return only what was requested */
204
    /* Return only what was requested */
185
 
205
 
186
    if (OutQuotient)
206
    if (OutQuotient)
187
    {
207
    {
188
        *OutQuotient = Quotient.Full;
208
        *OutQuotient = Quotient.Full;
189
    }
209
    }
190
    if (OutRemainder)
210
    if (OutRemainder)
191
    {
211
    {
192
        *OutRemainder = Remainder32;
212
        *OutRemainder = Remainder32;
193
    }
213
    }
194
 
214
 
195
    return_ACPI_STATUS (AE_OK);
215
    return_ACPI_STATUS (AE_OK);
196
}
216
}
197
 
217
 
198
 
218
 
199
/*******************************************************************************
219
/*******************************************************************************
200
 *
220
 *
201
 * FUNCTION:    AcpiUtDivide
221
 * FUNCTION:    AcpiUtDivide
202
 *
222
 *
203
 * PARAMETERS:  InDividend          - Dividend
223
 * PARAMETERS:  InDividend          - Dividend
204
 *              InDivisor           - Divisor
224
 *              InDivisor           - Divisor
205
 *              OutQuotient         - Pointer to where the quotient is returned
225
 *              OutQuotient         - Pointer to where the quotient is returned
206
 *              OutRemainder        - Pointer to where the remainder is returned
226
 *              OutRemainder        - Pointer to where the remainder is returned
207
 *
227
 *
208
 * RETURN:      Status (Checks for divide-by-zero)
228
 * RETURN:      Status (Checks for divide-by-zero)
209
 *
229
 *
210
 * DESCRIPTION: Perform a divide and modulo.
230
 * DESCRIPTION: Perform a divide and modulo.
211
 *
231
 *
212
 ******************************************************************************/
232
 ******************************************************************************/
213
 
233
 
214
ACPI_STATUS
234
ACPI_STATUS
215
AcpiUtDivide (
235
AcpiUtDivide (
216
    UINT64                  InDividend,
236
    UINT64                  InDividend,
217
    UINT64                  InDivisor,
237
    UINT64                  InDivisor,
218
    UINT64                  *OutQuotient,
238
    UINT64                  *OutQuotient,
219
    UINT64                  *OutRemainder)
239
    UINT64                  *OutRemainder)
220
{
240
{
221
    UINT64_OVERLAY          Dividend;
241
    UINT64_OVERLAY          Dividend;
222
    UINT64_OVERLAY          Divisor;
242
    UINT64_OVERLAY          Divisor;
223
    UINT64_OVERLAY          Quotient;
243
    UINT64_OVERLAY          Quotient;
224
    UINT64_OVERLAY          Remainder;
244
    UINT64_OVERLAY          Remainder;
225
    UINT64_OVERLAY          NormalizedDividend;
245
    UINT64_OVERLAY          NormalizedDividend;
226
    UINT64_OVERLAY          NormalizedDivisor;
246
    UINT64_OVERLAY          NormalizedDivisor;
227
    UINT32                  Partial1;
247
    UINT32                  Partial1;
228
    UINT64_OVERLAY          Partial2;
248
    UINT64_OVERLAY          Partial2;
229
    UINT64_OVERLAY          Partial3;
249
    UINT64_OVERLAY          Partial3;
230
 
250
 
231
 
251
 
232
    ACPI_FUNCTION_TRACE (UtDivide);
252
    ACPI_FUNCTION_TRACE (UtDivide);
233
 
253
 
234
 
254
 
235
    /* Always check for a zero divisor */
255
    /* Always check for a zero divisor */
236
 
256
 
237
    if (InDivisor == 0)
257
    if (InDivisor == 0)
238
    {
258
    {
239
        ACPI_ERROR ((AE_INFO, "Divide by zero"));
259
        ACPI_ERROR ((AE_INFO, "Divide by zero"));
240
        return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
260
        return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
241
    }
261
    }
242
 
262
 
243
    Divisor.Full  = InDivisor;
263
    Divisor.Full  = InDivisor;
244
    Dividend.Full = InDividend;
264
    Dividend.Full = InDividend;
245
    if (Divisor.Part.Hi == 0)
265
    if (Divisor.Part.Hi == 0)
246
    {
266
    {
247
        /*
267
        /*
248
         * 1) Simplest case is where the divisor is 32 bits, we can
268
         * 1) Simplest case is where the divisor is 32 bits, we can
249
         * just do two divides
269
         * just do two divides
250
         */
270
         */
251
        Remainder.Part.Hi = 0;
271
        Remainder.Part.Hi = 0;
252
 
272
 
253
        /*
273
        /*
254
         * The quotient is 64 bits, the remainder is always 32 bits,
274
         * The quotient is 64 bits, the remainder is always 32 bits,
255
         * and is generated by the second divide.
275
         * and is generated by the second divide.
256
         */
276
         */
257
        ACPI_DIV_64_BY_32 (0, Dividend.Part.Hi, Divisor.Part.Lo,
277
        ACPI_DIV_64_BY_32 (0, Dividend.Part.Hi, Divisor.Part.Lo,
258
                           Quotient.Part.Hi, Partial1);
278
                           Quotient.Part.Hi, Partial1);
259
        ACPI_DIV_64_BY_32 (Partial1, Dividend.Part.Lo, Divisor.Part.Lo,
279
        ACPI_DIV_64_BY_32 (Partial1, Dividend.Part.Lo, Divisor.Part.Lo,
260
                           Quotient.Part.Lo, Remainder.Part.Lo);
280
                           Quotient.Part.Lo, Remainder.Part.Lo);
261
    }
281
    }
262
 
282
 
263
    else
283
    else
264
    {
284
    {
265
        /*
285
        /*
266
         * 2) The general case where the divisor is a full 64 bits
286
         * 2) The general case where the divisor is a full 64 bits
267
         * is more difficult
287
         * is more difficult
268
         */
288
         */
269
        Quotient.Part.Hi   = 0;
289
        Quotient.Part.Hi   = 0;
270
        NormalizedDividend = Dividend;
290
        NormalizedDividend = Dividend;
271
        NormalizedDivisor  = Divisor;
291
        NormalizedDivisor  = Divisor;
272
 
292
 
273
        /* Normalize the operands (shift until the divisor is < 32 bits) */
293
        /* Normalize the operands (shift until the divisor is < 32 bits) */
274
 
294
 
275
        do
295
        do
276
        {
296
        {
277
            ACPI_SHIFT_RIGHT_64 (NormalizedDivisor.Part.Hi,
297
            ACPI_SHIFT_RIGHT_64 (NormalizedDivisor.Part.Hi,
278
                                 NormalizedDivisor.Part.Lo);
298
                                 NormalizedDivisor.Part.Lo);
279
            ACPI_SHIFT_RIGHT_64 (NormalizedDividend.Part.Hi,
299
            ACPI_SHIFT_RIGHT_64 (NormalizedDividend.Part.Hi,
280
                                 NormalizedDividend.Part.Lo);
300
                                 NormalizedDividend.Part.Lo);
281
 
301
 
282
        } while (NormalizedDivisor.Part.Hi != 0);
302
        } while (NormalizedDivisor.Part.Hi != 0);
283
 
303
 
284
        /* Partial divide */
304
        /* Partial divide */
285
 
305
 
286
        ACPI_DIV_64_BY_32 (NormalizedDividend.Part.Hi,
306
        ACPI_DIV_64_BY_32 (NormalizedDividend.Part.Hi,
287
                           NormalizedDividend.Part.Lo,
307
                           NormalizedDividend.Part.Lo,
288
                           NormalizedDivisor.Part.Lo,
308
                           NormalizedDivisor.Part.Lo,
289
                           Quotient.Part.Lo, Partial1);
309
                           Quotient.Part.Lo, Partial1);
290
 
310
 
291
        /*
311
        /*
292
         * The quotient is always 32 bits, and simply requires adjustment.
312
         * The quotient is always 32 bits, and simply requires adjustment.
293
         * The 64-bit remainder must be generated.
313
         * The 64-bit remainder must be generated.
294
         */
314
         */
295
        Partial1      = Quotient.Part.Lo * Divisor.Part.Hi;
315
        Partial1      = Quotient.Part.Lo * Divisor.Part.Hi;
296
        Partial2.Full = (UINT64) Quotient.Part.Lo * Divisor.Part.Lo;
316
        Partial2.Full = (UINT64) Quotient.Part.Lo * Divisor.Part.Lo;
297
        Partial3.Full = (UINT64) Partial2.Part.Hi + Partial1;
317
        Partial3.Full = (UINT64) Partial2.Part.Hi + Partial1;
298
 
318
 
299
        Remainder.Part.Hi = Partial3.Part.Lo;
319
        Remainder.Part.Hi = Partial3.Part.Lo;
300
        Remainder.Part.Lo = Partial2.Part.Lo;
320
        Remainder.Part.Lo = Partial2.Part.Lo;
301
 
321
 
302
        if (Partial3.Part.Hi == 0)
322
        if (Partial3.Part.Hi == 0)
303
        {
323
        {
304
            if (Partial3.Part.Lo >= Dividend.Part.Hi)
324
            if (Partial3.Part.Lo >= Dividend.Part.Hi)
305
            {
325
            {
306
                if (Partial3.Part.Lo == Dividend.Part.Hi)
326
                if (Partial3.Part.Lo == Dividend.Part.Hi)
307
                {
327
                {
308
                    if (Partial2.Part.Lo > Dividend.Part.Lo)
328
                    if (Partial2.Part.Lo > Dividend.Part.Lo)
309
                    {
329
                    {
310
                        Quotient.Part.Lo--;
330
                        Quotient.Part.Lo--;
311
                        Remainder.Full -= Divisor.Full;
331
                        Remainder.Full -= Divisor.Full;
312
                    }
332
                    }
313
                }
333
                }
314
                else
334
                else
315
                {
335
                {
316
                    Quotient.Part.Lo--;
336
                    Quotient.Part.Lo--;
317
                    Remainder.Full -= Divisor.Full;
337
                    Remainder.Full -= Divisor.Full;
318
                }
338
                }
319
            }
339
            }
320
 
340
 
321
            Remainder.Full    = Remainder.Full - Dividend.Full;
341
            Remainder.Full    = Remainder.Full - Dividend.Full;
322
            Remainder.Part.Hi = (UINT32) -((INT32) Remainder.Part.Hi);
342
            Remainder.Part.Hi = (UINT32) -((INT32) Remainder.Part.Hi);
323
            Remainder.Part.Lo = (UINT32) -((INT32) Remainder.Part.Lo);
343
            Remainder.Part.Lo = (UINT32) -((INT32) Remainder.Part.Lo);
324
 
344
 
325
            if (Remainder.Part.Lo)
345
            if (Remainder.Part.Lo)
326
            {
346
            {
327
                Remainder.Part.Hi--;
347
                Remainder.Part.Hi--;
328
            }
348
            }
329
        }
349
        }
330
    }
350
    }
331
 
351
 
332
    /* Return only what was requested */
352
    /* Return only what was requested */
333
 
353
 
334
    if (OutQuotient)
354
    if (OutQuotient)
335
    {
355
    {
336
        *OutQuotient = Quotient.Full;
356
        *OutQuotient = Quotient.Full;
337
    }
357
    }
338
    if (OutRemainder)
358
    if (OutRemainder)
339
    {
359
    {
340
        *OutRemainder = Remainder.Full;
360
        *OutRemainder = Remainder.Full;
341
    }
361
    }
342
 
362
 
343
    return_ACPI_STATUS (AE_OK);
363
    return_ACPI_STATUS (AE_OK);
344
}
364
}
345
 
365
 
346
#else
366
#else
347
 
367
 
348
/*******************************************************************************
368
/*******************************************************************************
349
 *
369
 *
350
 * FUNCTION:    AcpiUtShortDivide, AcpiUtDivide
370
 * FUNCTION:    AcpiUtShortDivide, AcpiUtDivide
351
 *
371
 *
352
 * PARAMETERS:  See function headers above
372
 * PARAMETERS:  See function headers above
353
 *
373
 *
354
 * DESCRIPTION: Native versions of the UtDivide functions. Use these if either
374
 * DESCRIPTION: Native versions of the UtDivide functions. Use these if either
355
 *              1) The target is a 64-bit platform and therefore 64-bit
375
 *              1) The target is a 64-bit platform and therefore 64-bit
356
 *                 integer math is supported directly by the machine.
376
 *                 integer math is supported directly by the machine.
357
 *              2) The target is a 32-bit or 16-bit platform, and the
377
 *              2) The target is a 32-bit or 16-bit platform, and the
358
 *                 double-precision integer math library is available to
378
 *                 double-precision integer math library is available to
359
 *                 perform the divide.
379
 *                 perform the divide.
360
 *
380
 *
361
 ******************************************************************************/
381
 ******************************************************************************/
362
 
382
 
363
ACPI_STATUS
383
ACPI_STATUS
364
AcpiUtShortDivide (
384
AcpiUtShortDivide (
365
    UINT64                  InDividend,
385
    UINT64                  InDividend,
366
    UINT32                  Divisor,
386
    UINT32                  Divisor,
367
    UINT64                  *OutQuotient,
387
    UINT64                  *OutQuotient,
368
    UINT32                  *OutRemainder)
388
    UINT32                  *OutRemainder)
369
{
389
{
370
 
390
 
371
    ACPI_FUNCTION_TRACE (UtShortDivide);
391
    ACPI_FUNCTION_TRACE (UtShortDivide);
372
 
392
 
373
 
393
 
374
    /* Always check for a zero divisor */
394
    /* Always check for a zero divisor */
375
 
395
 
376
    if (Divisor == 0)
396
    if (Divisor == 0)
377
    {
397
    {
378
        ACPI_ERROR ((AE_INFO, "Divide by zero"));
398
        ACPI_ERROR ((AE_INFO, "Divide by zero"));
379
        return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
399
        return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
380
    }
400
    }
381
 
401
 
382
    /* Return only what was requested */
402
    /* Return only what was requested */
383
 
403
 
384
    if (OutQuotient)
404
    if (OutQuotient)
385
    {
405
    {
386
        *OutQuotient = InDividend / Divisor;
406
        *OutQuotient = InDividend / Divisor;
387
    }
407
    }
388
    if (OutRemainder)
408
    if (OutRemainder)
389
    {
409
    {
390
        *OutRemainder = (UINT32) (InDividend % Divisor);
410
        *OutRemainder = (UINT32) (InDividend % Divisor);
391
    }
411
    }
392
 
412
 
393
    return_ACPI_STATUS (AE_OK);
413
    return_ACPI_STATUS (AE_OK);
394
}
414
}
395
 
415
 
396
ACPI_STATUS
416
ACPI_STATUS
397
AcpiUtDivide (
417
AcpiUtDivide (
398
    UINT64                  InDividend,
418
    UINT64                  InDividend,
399
    UINT64                  InDivisor,
419
    UINT64                  InDivisor,
400
    UINT64                  *OutQuotient,
420
    UINT64                  *OutQuotient,
401
    UINT64                  *OutRemainder)
421
    UINT64                  *OutRemainder)
402
{
422
{
403
    ACPI_FUNCTION_TRACE (UtDivide);
423
    ACPI_FUNCTION_TRACE (UtDivide);
404
 
424
 
405
 
425
 
406
    /* Always check for a zero divisor */
426
    /* Always check for a zero divisor */
407
 
427
 
408
    if (InDivisor == 0)
428
    if (InDivisor == 0)
409
    {
429
    {
410
        ACPI_ERROR ((AE_INFO, "Divide by zero"));
430
        ACPI_ERROR ((AE_INFO, "Divide by zero"));
411
        return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
431
        return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO);
412
    }
432
    }
413
 
433
 
414
 
434
 
415
    /* Return only what was requested */
435
    /* Return only what was requested */
416
 
436
 
417
    if (OutQuotient)
437
    if (OutQuotient)
418
    {
438
    {
419
        *OutQuotient = InDividend / InDivisor;
439
        *OutQuotient = InDividend / InDivisor;
420
    }
440
    }
421
    if (OutRemainder)
441
    if (OutRemainder)
422
    {
442
    {
423
        *OutRemainder = InDividend % InDivisor;
443
        *OutRemainder = InDividend % InDivisor;
424
    }
444
    }
425
 
445
 
426
    return_ACPI_STATUS (AE_OK);
446
    return_ACPI_STATUS (AE_OK);
427
}
447
}
428
 
448
 
429
#endif
449
#endif