Loading...
1/*******************************************************************************
2 *
3 * Module Name: utmath - Integer math support routines
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46
47#define _COMPONENT ACPI_UTILITIES
48ACPI_MODULE_NAME("utmath")
49
50/*
51 * Optional support for 64-bit double-precision integer divide. This code
52 * is configurable and is implemented in order to support 32-bit kernel
53 * environments where a 64-bit double-precision math library is not available.
54 *
55 * Support for a more normal 64-bit divide/modulo (with check for a divide-
56 * by-zero) appears after this optional section of code.
57 */
58#ifndef ACPI_USE_NATIVE_DIVIDE
59/* Structures used only for 64-bit divide */
60typedef struct uint64_struct {
61 u32 lo;
62 u32 hi;
63
64} uint64_struct;
65
66typedef union uint64_overlay {
67 u64 full;
68 struct uint64_struct part;
69
70} uint64_overlay;
71
72/*******************************************************************************
73 *
74 * FUNCTION: acpi_ut_short_divide
75 *
76 * PARAMETERS: Dividend - 64-bit dividend
77 * Divisor - 32-bit divisor
78 * out_quotient - Pointer to where the quotient is returned
79 * out_remainder - Pointer to where the remainder is returned
80 *
81 * RETURN: Status (Checks for divide-by-zero)
82 *
83 * DESCRIPTION: Perform a short (maximum 64 bits divided by 32 bits)
84 * divide and modulo. The result is a 64-bit quotient and a
85 * 32-bit remainder.
86 *
87 ******************************************************************************/
88
89acpi_status
90acpi_ut_short_divide(u64 dividend,
91 u32 divisor, u64 *out_quotient, u32 *out_remainder)
92{
93 union uint64_overlay dividend_ovl;
94 union uint64_overlay quotient;
95 u32 remainder32;
96
97 ACPI_FUNCTION_TRACE(ut_short_divide);
98
99 /* Always check for a zero divisor */
100
101 if (divisor == 0) {
102 ACPI_ERROR((AE_INFO, "Divide by zero"));
103 return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO);
104 }
105
106 dividend_ovl.full = dividend;
107
108 /*
109 * The quotient is 64 bits, the remainder is always 32 bits,
110 * and is generated by the second divide.
111 */
112 ACPI_DIV_64_BY_32(0, dividend_ovl.part.hi, divisor,
113 quotient.part.hi, remainder32);
114 ACPI_DIV_64_BY_32(remainder32, dividend_ovl.part.lo, divisor,
115 quotient.part.lo, remainder32);
116
117 /* Return only what was requested */
118
119 if (out_quotient) {
120 *out_quotient = quotient.full;
121 }
122 if (out_remainder) {
123 *out_remainder = remainder32;
124 }
125
126 return_ACPI_STATUS(AE_OK);
127}
128
129/*******************************************************************************
130 *
131 * FUNCTION: acpi_ut_divide
132 *
133 * PARAMETERS: in_dividend - Dividend
134 * in_divisor - Divisor
135 * out_quotient - Pointer to where the quotient is returned
136 * out_remainder - Pointer to where the remainder is returned
137 *
138 * RETURN: Status (Checks for divide-by-zero)
139 *
140 * DESCRIPTION: Perform a divide and modulo.
141 *
142 ******************************************************************************/
143
144acpi_status
145acpi_ut_divide(u64 in_dividend,
146 u64 in_divisor, u64 *out_quotient, u64 *out_remainder)
147{
148 union uint64_overlay dividend;
149 union uint64_overlay divisor;
150 union uint64_overlay quotient;
151 union uint64_overlay remainder;
152 union uint64_overlay normalized_dividend;
153 union uint64_overlay normalized_divisor;
154 u32 partial1;
155 union uint64_overlay partial2;
156 union uint64_overlay partial3;
157
158 ACPI_FUNCTION_TRACE(ut_divide);
159
160 /* Always check for a zero divisor */
161
162 if (in_divisor == 0) {
163 ACPI_ERROR((AE_INFO, "Divide by zero"));
164 return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO);
165 }
166
167 divisor.full = in_divisor;
168 dividend.full = in_dividend;
169 if (divisor.part.hi == 0) {
170 /*
171 * 1) Simplest case is where the divisor is 32 bits, we can
172 * just do two divides
173 */
174 remainder.part.hi = 0;
175
176 /*
177 * The quotient is 64 bits, the remainder is always 32 bits,
178 * and is generated by the second divide.
179 */
180 ACPI_DIV_64_BY_32(0, dividend.part.hi, divisor.part.lo,
181 quotient.part.hi, partial1);
182 ACPI_DIV_64_BY_32(partial1, dividend.part.lo, divisor.part.lo,
183 quotient.part.lo, remainder.part.lo);
184 }
185
186 else {
187 /*
188 * 2) The general case where the divisor is a full 64 bits
189 * is more difficult
190 */
191 quotient.part.hi = 0;
192 normalized_dividend = dividend;
193 normalized_divisor = divisor;
194
195 /* Normalize the operands (shift until the divisor is < 32 bits) */
196
197 do {
198 ACPI_SHIFT_RIGHT_64(normalized_divisor.part.hi,
199 normalized_divisor.part.lo);
200 ACPI_SHIFT_RIGHT_64(normalized_dividend.part.hi,
201 normalized_dividend.part.lo);
202
203 } while (normalized_divisor.part.hi != 0);
204
205 /* Partial divide */
206
207 ACPI_DIV_64_BY_32(normalized_dividend.part.hi,
208 normalized_dividend.part.lo,
209 normalized_divisor.part.lo,
210 quotient.part.lo, partial1);
211
212 /*
213 * The quotient is always 32 bits, and simply requires adjustment.
214 * The 64-bit remainder must be generated.
215 */
216 partial1 = quotient.part.lo * divisor.part.hi;
217 partial2.full = (u64) quotient.part.lo * divisor.part.lo;
218 partial3.full = (u64) partial2.part.hi + partial1;
219
220 remainder.part.hi = partial3.part.lo;
221 remainder.part.lo = partial2.part.lo;
222
223 if (partial3.part.hi == 0) {
224 if (partial3.part.lo >= dividend.part.hi) {
225 if (partial3.part.lo == dividend.part.hi) {
226 if (partial2.part.lo > dividend.part.lo) {
227 quotient.part.lo--;
228 remainder.full -= divisor.full;
229 }
230 } else {
231 quotient.part.lo--;
232 remainder.full -= divisor.full;
233 }
234 }
235
236 remainder.full = remainder.full - dividend.full;
237 remainder.part.hi = (u32) - ((s32) remainder.part.hi);
238 remainder.part.lo = (u32) - ((s32) remainder.part.lo);
239
240 if (remainder.part.lo) {
241 remainder.part.hi--;
242 }
243 }
244 }
245
246 /* Return only what was requested */
247
248 if (out_quotient) {
249 *out_quotient = quotient.full;
250 }
251 if (out_remainder) {
252 *out_remainder = remainder.full;
253 }
254
255 return_ACPI_STATUS(AE_OK);
256}
257
258#else
259/*******************************************************************************
260 *
261 * FUNCTION: acpi_ut_short_divide, acpi_ut_divide
262 *
263 * PARAMETERS: See function headers above
264 *
265 * DESCRIPTION: Native versions of the ut_divide functions. Use these if either
266 * 1) The target is a 64-bit platform and therefore 64-bit
267 * integer math is supported directly by the machine.
268 * 2) The target is a 32-bit or 16-bit platform, and the
269 * double-precision integer math library is available to
270 * perform the divide.
271 *
272 ******************************************************************************/
273acpi_status
274acpi_ut_short_divide(u64 in_dividend,
275 u32 divisor, u64 *out_quotient, u32 *out_remainder)
276{
277
278 ACPI_FUNCTION_TRACE(ut_short_divide);
279
280 /* Always check for a zero divisor */
281
282 if (divisor == 0) {
283 ACPI_ERROR((AE_INFO, "Divide by zero"));
284 return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO);
285 }
286
287 /* Return only what was requested */
288
289 if (out_quotient) {
290 *out_quotient = in_dividend / divisor;
291 }
292 if (out_remainder) {
293 *out_remainder = (u32) (in_dividend % divisor);
294 }
295
296 return_ACPI_STATUS(AE_OK);
297}
298
299acpi_status
300acpi_ut_divide(u64 in_dividend,
301 u64 in_divisor, u64 *out_quotient, u64 *out_remainder)
302{
303 ACPI_FUNCTION_TRACE(ut_divide);
304
305 /* Always check for a zero divisor */
306
307 if (in_divisor == 0) {
308 ACPI_ERROR((AE_INFO, "Divide by zero"));
309 return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO);
310 }
311
312 /* Return only what was requested */
313
314 if (out_quotient) {
315 *out_quotient = in_dividend / in_divisor;
316 }
317 if (out_remainder) {
318 *out_remainder = in_dividend % in_divisor;
319 }
320
321 return_ACPI_STATUS(AE_OK);
322}
323
324#endif
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2/*******************************************************************************
3 *
4 * Module Name: utmath - Integer math support routines
5 *
6 ******************************************************************************/
7
8#include <acpi/acpi.h>
9#include "accommon.h"
10
11#define _COMPONENT ACPI_UTILITIES
12ACPI_MODULE_NAME("utmath")
13
14/* Structures used only for 64-bit divide */
15typedef struct uint64_struct {
16 u32 lo;
17 u32 hi;
18
19} uint64_struct;
20
21typedef union uint64_overlay {
22 u64 full;
23 struct uint64_struct part;
24
25} uint64_overlay;
26
27/*
28 * Optional support for 64-bit double-precision integer multiply and shift.
29 * This code is configurable and is implemented in order to support 32-bit
30 * kernel environments where a 64-bit double-precision math library is not
31 * available.
32 */
33#ifndef ACPI_USE_NATIVE_MATH64
34
35/*******************************************************************************
36 *
37 * FUNCTION: acpi_ut_short_multiply
38 *
39 * PARAMETERS: multiplicand - 64-bit multiplicand
40 * multiplier - 32-bit multiplier
41 * out_product - Pointer to where the product is returned
42 *
43 * DESCRIPTION: Perform a short multiply.
44 *
45 ******************************************************************************/
46
47acpi_status
48acpi_ut_short_multiply(u64 multiplicand, u32 multiplier, u64 *out_product)
49{
50 union uint64_overlay multiplicand_ovl;
51 union uint64_overlay product;
52 u32 carry32;
53
54 ACPI_FUNCTION_TRACE(ut_short_multiply);
55
56 multiplicand_ovl.full = multiplicand;
57
58 /*
59 * The Product is 64 bits, the carry is always 32 bits,
60 * and is generated by the second multiply.
61 */
62 ACPI_MUL_64_BY_32(0, multiplicand_ovl.part.hi, multiplier,
63 product.part.hi, carry32);
64
65 ACPI_MUL_64_BY_32(0, multiplicand_ovl.part.lo, multiplier,
66 product.part.lo, carry32);
67
68 product.part.hi += carry32;
69
70 /* Return only what was requested */
71
72 if (out_product) {
73 *out_product = product.full;
74 }
75
76 return_ACPI_STATUS(AE_OK);
77}
78
79/*******************************************************************************
80 *
81 * FUNCTION: acpi_ut_short_shift_left
82 *
83 * PARAMETERS: operand - 64-bit shift operand
84 * count - 32-bit shift count
85 * out_result - Pointer to where the result is returned
86 *
87 * DESCRIPTION: Perform a short left shift.
88 *
89 ******************************************************************************/
90
91acpi_status acpi_ut_short_shift_left(u64 operand, u32 count, u64 *out_result)
92{
93 union uint64_overlay operand_ovl;
94
95 ACPI_FUNCTION_TRACE(ut_short_shift_left);
96
97 operand_ovl.full = operand;
98
99 if ((count & 63) >= 32) {
100 operand_ovl.part.hi = operand_ovl.part.lo;
101 operand_ovl.part.lo = 0;
102 count = (count & 63) - 32;
103 }
104 ACPI_SHIFT_LEFT_64_BY_32(operand_ovl.part.hi,
105 operand_ovl.part.lo, count);
106
107 /* Return only what was requested */
108
109 if (out_result) {
110 *out_result = operand_ovl.full;
111 }
112
113 return_ACPI_STATUS(AE_OK);
114}
115
116/*******************************************************************************
117 *
118 * FUNCTION: acpi_ut_short_shift_right
119 *
120 * PARAMETERS: operand - 64-bit shift operand
121 * count - 32-bit shift count
122 * out_result - Pointer to where the result is returned
123 *
124 * DESCRIPTION: Perform a short right shift.
125 *
126 ******************************************************************************/
127
128acpi_status acpi_ut_short_shift_right(u64 operand, u32 count, u64 *out_result)
129{
130 union uint64_overlay operand_ovl;
131
132 ACPI_FUNCTION_TRACE(ut_short_shift_right);
133
134 operand_ovl.full = operand;
135
136 if ((count & 63) >= 32) {
137 operand_ovl.part.lo = operand_ovl.part.hi;
138 operand_ovl.part.hi = 0;
139 count = (count & 63) - 32;
140 }
141 ACPI_SHIFT_RIGHT_64_BY_32(operand_ovl.part.hi,
142 operand_ovl.part.lo, count);
143
144 /* Return only what was requested */
145
146 if (out_result) {
147 *out_result = operand_ovl.full;
148 }
149
150 return_ACPI_STATUS(AE_OK);
151}
152#else
153
154/*******************************************************************************
155 *
156 * FUNCTION: acpi_ut_short_multiply
157 *
158 * PARAMETERS: See function headers above
159 *
160 * DESCRIPTION: Native version of the ut_short_multiply function.
161 *
162 ******************************************************************************/
163
164acpi_status
165acpi_ut_short_multiply(u64 multiplicand, u32 multiplier, u64 *out_product)
166{
167
168 ACPI_FUNCTION_TRACE(ut_short_multiply);
169
170 /* Return only what was requested */
171
172 if (out_product) {
173 *out_product = multiplicand * multiplier;
174 }
175
176 return_ACPI_STATUS(AE_OK);
177}
178
179/*******************************************************************************
180 *
181 * FUNCTION: acpi_ut_short_shift_left
182 *
183 * PARAMETERS: See function headers above
184 *
185 * DESCRIPTION: Native version of the ut_short_shift_left function.
186 *
187 ******************************************************************************/
188
189acpi_status acpi_ut_short_shift_left(u64 operand, u32 count, u64 *out_result)
190{
191
192 ACPI_FUNCTION_TRACE(ut_short_shift_left);
193
194 /* Return only what was requested */
195
196 if (out_result) {
197 *out_result = operand << count;
198 }
199
200 return_ACPI_STATUS(AE_OK);
201}
202
203/*******************************************************************************
204 *
205 * FUNCTION: acpi_ut_short_shift_right
206 *
207 * PARAMETERS: See function headers above
208 *
209 * DESCRIPTION: Native version of the ut_short_shift_right function.
210 *
211 ******************************************************************************/
212
213acpi_status acpi_ut_short_shift_right(u64 operand, u32 count, u64 *out_result)
214{
215
216 ACPI_FUNCTION_TRACE(ut_short_shift_right);
217
218 /* Return only what was requested */
219
220 if (out_result) {
221 *out_result = operand >> count;
222 }
223
224 return_ACPI_STATUS(AE_OK);
225}
226#endif
227
228/*
229 * Optional support for 64-bit double-precision integer divide. This code
230 * is configurable and is implemented in order to support 32-bit kernel
231 * environments where a 64-bit double-precision math library is not available.
232 *
233 * Support for a more normal 64-bit divide/modulo (with check for a divide-
234 * by-zero) appears after this optional section of code.
235 */
236#ifndef ACPI_USE_NATIVE_DIVIDE
237
238/*******************************************************************************
239 *
240 * FUNCTION: acpi_ut_short_divide
241 *
242 * PARAMETERS: dividend - 64-bit dividend
243 * divisor - 32-bit divisor
244 * out_quotient - Pointer to where the quotient is returned
245 * out_remainder - Pointer to where the remainder is returned
246 *
247 * RETURN: Status (Checks for divide-by-zero)
248 *
249 * DESCRIPTION: Perform a short (maximum 64 bits divided by 32 bits)
250 * divide and modulo. The result is a 64-bit quotient and a
251 * 32-bit remainder.
252 *
253 ******************************************************************************/
254
255acpi_status
256acpi_ut_short_divide(u64 dividend,
257 u32 divisor, u64 *out_quotient, u32 *out_remainder)
258{
259 union uint64_overlay dividend_ovl;
260 union uint64_overlay quotient;
261 u32 remainder32;
262
263 ACPI_FUNCTION_TRACE(ut_short_divide);
264
265 /* Always check for a zero divisor */
266
267 if (divisor == 0) {
268 ACPI_ERROR((AE_INFO, "Divide by zero"));
269 return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO);
270 }
271
272 dividend_ovl.full = dividend;
273
274 /*
275 * The quotient is 64 bits, the remainder is always 32 bits,
276 * and is generated by the second divide.
277 */
278 ACPI_DIV_64_BY_32(0, dividend_ovl.part.hi, divisor,
279 quotient.part.hi, remainder32);
280
281 ACPI_DIV_64_BY_32(remainder32, dividend_ovl.part.lo, divisor,
282 quotient.part.lo, remainder32);
283
284 /* Return only what was requested */
285
286 if (out_quotient) {
287 *out_quotient = quotient.full;
288 }
289 if (out_remainder) {
290 *out_remainder = remainder32;
291 }
292
293 return_ACPI_STATUS(AE_OK);
294}
295
296/*******************************************************************************
297 *
298 * FUNCTION: acpi_ut_divide
299 *
300 * PARAMETERS: in_dividend - Dividend
301 * in_divisor - Divisor
302 * out_quotient - Pointer to where the quotient is returned
303 * out_remainder - Pointer to where the remainder is returned
304 *
305 * RETURN: Status (Checks for divide-by-zero)
306 *
307 * DESCRIPTION: Perform a divide and modulo.
308 *
309 ******************************************************************************/
310
311acpi_status
312acpi_ut_divide(u64 in_dividend,
313 u64 in_divisor, u64 *out_quotient, u64 *out_remainder)
314{
315 union uint64_overlay dividend;
316 union uint64_overlay divisor;
317 union uint64_overlay quotient;
318 union uint64_overlay remainder;
319 union uint64_overlay normalized_dividend;
320 union uint64_overlay normalized_divisor;
321 u32 partial1;
322 union uint64_overlay partial2;
323 union uint64_overlay partial3;
324
325 ACPI_FUNCTION_TRACE(ut_divide);
326
327 /* Always check for a zero divisor */
328
329 if (in_divisor == 0) {
330 ACPI_ERROR((AE_INFO, "Divide by zero"));
331 return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO);
332 }
333
334 divisor.full = in_divisor;
335 dividend.full = in_dividend;
336 if (divisor.part.hi == 0) {
337 /*
338 * 1) Simplest case is where the divisor is 32 bits, we can
339 * just do two divides
340 */
341 remainder.part.hi = 0;
342
343 /*
344 * The quotient is 64 bits, the remainder is always 32 bits,
345 * and is generated by the second divide.
346 */
347 ACPI_DIV_64_BY_32(0, dividend.part.hi, divisor.part.lo,
348 quotient.part.hi, partial1);
349
350 ACPI_DIV_64_BY_32(partial1, dividend.part.lo, divisor.part.lo,
351 quotient.part.lo, remainder.part.lo);
352 }
353
354 else {
355 /*
356 * 2) The general case where the divisor is a full 64 bits
357 * is more difficult
358 */
359 quotient.part.hi = 0;
360 normalized_dividend = dividend;
361 normalized_divisor = divisor;
362
363 /* Normalize the operands (shift until the divisor is < 32 bits) */
364
365 do {
366 ACPI_SHIFT_RIGHT_64(normalized_divisor.part.hi,
367 normalized_divisor.part.lo);
368 ACPI_SHIFT_RIGHT_64(normalized_dividend.part.hi,
369 normalized_dividend.part.lo);
370
371 } while (normalized_divisor.part.hi != 0);
372
373 /* Partial divide */
374
375 ACPI_DIV_64_BY_32(normalized_dividend.part.hi,
376 normalized_dividend.part.lo,
377 normalized_divisor.part.lo, quotient.part.lo,
378 partial1);
379
380 /*
381 * The quotient is always 32 bits, and simply requires
382 * adjustment. The 64-bit remainder must be generated.
383 */
384 partial1 = quotient.part.lo * divisor.part.hi;
385 partial2.full = (u64) quotient.part.lo * divisor.part.lo;
386 partial3.full = (u64) partial2.part.hi + partial1;
387
388 remainder.part.hi = partial3.part.lo;
389 remainder.part.lo = partial2.part.lo;
390
391 if (partial3.part.hi == 0) {
392 if (partial3.part.lo >= dividend.part.hi) {
393 if (partial3.part.lo == dividend.part.hi) {
394 if (partial2.part.lo > dividend.part.lo) {
395 quotient.part.lo--;
396 remainder.full -= divisor.full;
397 }
398 } else {
399 quotient.part.lo--;
400 remainder.full -= divisor.full;
401 }
402 }
403
404 remainder.full = remainder.full - dividend.full;
405 remainder.part.hi = (u32)-((s32)remainder.part.hi);
406 remainder.part.lo = (u32)-((s32)remainder.part.lo);
407
408 if (remainder.part.lo) {
409 remainder.part.hi--;
410 }
411 }
412 }
413
414 /* Return only what was requested */
415
416 if (out_quotient) {
417 *out_quotient = quotient.full;
418 }
419 if (out_remainder) {
420 *out_remainder = remainder.full;
421 }
422
423 return_ACPI_STATUS(AE_OK);
424}
425
426#else
427
428/*******************************************************************************
429 *
430 * FUNCTION: acpi_ut_short_divide, acpi_ut_divide
431 *
432 * PARAMETERS: See function headers above
433 *
434 * DESCRIPTION: Native versions of the ut_divide functions. Use these if either
435 * 1) The target is a 64-bit platform and therefore 64-bit
436 * integer math is supported directly by the machine.
437 * 2) The target is a 32-bit or 16-bit platform, and the
438 * double-precision integer math library is available to
439 * perform the divide.
440 *
441 ******************************************************************************/
442
443acpi_status
444acpi_ut_short_divide(u64 in_dividend,
445 u32 divisor, u64 *out_quotient, u32 *out_remainder)
446{
447
448 ACPI_FUNCTION_TRACE(ut_short_divide);
449
450 /* Always check for a zero divisor */
451
452 if (divisor == 0) {
453 ACPI_ERROR((AE_INFO, "Divide by zero"));
454 return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO);
455 }
456
457 /* Return only what was requested */
458
459 if (out_quotient) {
460 *out_quotient = in_dividend / divisor;
461 }
462 if (out_remainder) {
463 *out_remainder = (u32) (in_dividend % divisor);
464 }
465
466 return_ACPI_STATUS(AE_OK);
467}
468
469acpi_status
470acpi_ut_divide(u64 in_dividend,
471 u64 in_divisor, u64 *out_quotient, u64 *out_remainder)
472{
473 ACPI_FUNCTION_TRACE(ut_divide);
474
475 /* Always check for a zero divisor */
476
477 if (in_divisor == 0) {
478 ACPI_ERROR((AE_INFO, "Divide by zero"));
479 return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO);
480 }
481
482 /* Return only what was requested */
483
484 if (out_quotient) {
485 *out_quotient = in_dividend / in_divisor;
486 }
487 if (out_remainder) {
488 *out_remainder = in_dividend % in_divisor;
489 }
490
491 return_ACPI_STATUS(AE_OK);
492}
493
494#endif