Linux Audio

Check our new training course

Loading...
v3.1
 
  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
v6.9.4
  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