ReactOS 0.4.16-dev-257-g6aa11ac
utmath.c File Reference
#include "acpi.h"
#include "accommon.h"
Include dependency graph for utmath.c:

Go to the source code of this file.

Classes

struct  uint64_struct
 
union  uint64_overlay
 

Macros

#define _COMPONENT   ACPI_UTILITIES
 

Typedefs

typedef struct uint64_struct UINT64_STRUCT
 
typedef union uint64_overlay UINT64_OVERLAY
 

Functions

ACPI_STATUS AcpiUtShortMultiply (UINT64 Multiplicand, UINT32 Multiplier, UINT64 *OutProduct)
 
ACPI_STATUS AcpiUtShortShiftLeft (UINT64 Operand, UINT32 Count, UINT64 *OutResult)
 
ACPI_STATUS AcpiUtShortShiftRight (UINT64 Operand, UINT32 Count, UINT64 *OutResult)
 
ACPI_STATUS AcpiUtShortDivide (UINT64 Dividend, UINT32 Divisor, UINT64 *OutQuotient, UINT32 *OutRemainder)
 
ACPI_STATUS AcpiUtDivide (UINT64 InDividend, UINT64 InDivisor, UINT64 *OutQuotient, UINT64 *OutRemainder)
 

Macro Definition Documentation

◆ _COMPONENT

#define _COMPONENT   ACPI_UTILITIES

Definition at line 48 of file utmath.c.

Typedef Documentation

◆ UINT64_OVERLAY

◆ UINT64_STRUCT

Function Documentation

◆ AcpiUtDivide()

ACPI_STATUS AcpiUtDivide ( UINT64  InDividend,
UINT64  InDivisor,
UINT64 OutQuotient,
UINT64 OutRemainder 
)

Definition at line 402 of file utmath.c.

407{
408 UINT64_OVERLAY Dividend;
410 UINT64_OVERLAY Quotient;
412 UINT64_OVERLAY NormalizedDividend;
413 UINT64_OVERLAY NormalizedDivisor;
414 UINT32 Partial1;
415 UINT64_OVERLAY Partial2;
416 UINT64_OVERLAY Partial3;
417
418
419 ACPI_FUNCTION_TRACE (UtDivide);
420
421
422 /* Always check for a zero divisor */
423
424 if (InDivisor == 0)
425 {
426 ACPI_ERROR ((AE_INFO, "Divide by zero"));
428 }
429
430 Divisor.Full = InDivisor;
431 Dividend.Full = InDividend;
432 if (Divisor.Part.Hi == 0)
433 {
434 /*
435 * 1) Simplest case is where the divisor is 32 bits, we can
436 * just do two divides
437 */
438 Remainder.Part.Hi = 0;
439
440 /*
441 * The quotient is 64 bits, the remainder is always 32 bits,
442 * and is generated by the second divide.
443 */
444 ACPI_DIV_64_BY_32 (0, Dividend.Part.Hi, Divisor.Part.Lo,
445 Quotient.Part.Hi, Partial1);
446
447 ACPI_DIV_64_BY_32 (Partial1, Dividend.Part.Lo, Divisor.Part.Lo,
448 Quotient.Part.Lo, Remainder.Part.Lo);
449 }
450
451 else
452 {
453 /*
454 * 2) The general case where the divisor is a full 64 bits
455 * is more difficult
456 */
457 Quotient.Part.Hi = 0;
458 NormalizedDividend = Dividend;
459 NormalizedDivisor = Divisor;
460
461 /* Normalize the operands (shift until the divisor is < 32 bits) */
462
463 do
464 {
466 NormalizedDivisor.Part.Hi, NormalizedDivisor.Part.Lo);
468 NormalizedDividend.Part.Hi, NormalizedDividend.Part.Lo);
469
470 } while (NormalizedDivisor.Part.Hi != 0);
471
472 /* Partial divide */
473
474 ACPI_DIV_64_BY_32 (
475 NormalizedDividend.Part.Hi, NormalizedDividend.Part.Lo,
476 NormalizedDivisor.Part.Lo, Quotient.Part.Lo, Partial1);
477
478 /*
479 * The quotient is always 32 bits, and simply requires
480 * adjustment. The 64-bit remainder must be generated.
481 */
482 Partial1 = Quotient.Part.Lo * Divisor.Part.Hi;
483 Partial2.Full = (UINT64) Quotient.Part.Lo * Divisor.Part.Lo;
484 Partial3.Full = (UINT64) Partial2.Part.Hi + Partial1;
485
486 Remainder.Part.Hi = Partial3.Part.Lo;
487 Remainder.Part.Lo = Partial2.Part.Lo;
488
489 if (Partial3.Part.Hi == 0)
490 {
491 if (Partial3.Part.Lo >= Dividend.Part.Hi)
492 {
493 if (Partial3.Part.Lo == Dividend.Part.Hi)
494 {
495 if (Partial2.Part.Lo > Dividend.Part.Lo)
496 {
497 Quotient.Part.Lo--;
498 Remainder.Full -= Divisor.Full;
499 }
500 }
501 else
502 {
503 Quotient.Part.Lo--;
504 Remainder.Full -= Divisor.Full;
505 }
506 }
507
508 Remainder.Full = Remainder.Full - Dividend.Full;
509 Remainder.Part.Hi = (UINT32) -((INT32) Remainder.Part.Hi);
510 Remainder.Part.Lo = (UINT32) -((INT32) Remainder.Part.Lo);
511
512 if (Remainder.Part.Lo)
513 {
514 Remainder.Part.Hi--;
515 }
516 }
517 }
518
519 /* Return only what was requested */
520
521 if (OutQuotient)
522 {
523 *OutQuotient = Quotient.Full;
524 }
525 if (OutRemainder)
526 {
527 *OutRemainder = Remainder.Full;
528 }
529
531}
signed int INT32
unsigned long long UINT64
unsigned int UINT32
#define AE_AML_DIVIDE_BY_ZERO
Definition: acexcep.h:191
#define AE_OK
Definition: acexcep.h:97
#define ACPI_SHIFT_RIGHT_64(n_hi, n_lo)
Definition: acos2.h:84
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
#define AE_INFO
Definition: acoutput.h:230
UINT32 Hi
Definition: utmath.c:56
UINT32 Lo
Definition: utmath.c:55
UINT64 Full
Definition: utmath.c:62
UINT64_STRUCT Part
Definition: utmath.c:63
_In_ LARGE_INTEGER Divisor
Definition: rtlfuncs.h:3061
_In_ LARGE_INTEGER _Out_opt_ PLARGE_INTEGER Remainder
Definition: rtlfuncs.h:3062

Referenced by AcpiExOpcode_2A_1T_1R(), AcpiExOpcode_2A_2T_1R(), and AcpiUtPutNumber().

◆ AcpiUtShortDivide()

ACPI_STATUS AcpiUtShortDivide ( UINT64  Dividend,
UINT32  Divisor,
UINT64 OutQuotient,
UINT32 OutRemainder 
)

Definition at line 337 of file utmath.c.

342{
343 UINT64_OVERLAY DividendOvl;
344 UINT64_OVERLAY Quotient;
345 UINT32 Remainder32;
346
347
348 ACPI_FUNCTION_TRACE (UtShortDivide);
349
350
351 /* Always check for a zero divisor */
352
353 if (Divisor == 0)
354 {
355 ACPI_ERROR ((AE_INFO, "Divide by zero"));
357 }
358
359 DividendOvl.Full = Dividend;
360
361 /*
362 * The quotient is 64 bits, the remainder is always 32 bits,
363 * and is generated by the second divide.
364 */
365 ACPI_DIV_64_BY_32 (0, DividendOvl.Part.Hi, Divisor,
366 Quotient.Part.Hi, Remainder32);
367
368 ACPI_DIV_64_BY_32 (Remainder32, DividendOvl.Part.Lo, Divisor,
369 Quotient.Part.Lo, Remainder32);
370
371 /* Return only what was requested */
372
373 if (OutQuotient)
374 {
375 *OutQuotient = Quotient.Full;
376 }
377 if (OutRemainder)
378 {
379 *OutRemainder = Remainder32;
380 }
381
383}

Referenced by AcpiExConvertToAscii(), AcpiExDigitsNeeded(), AcpiExIntegerToString(), AcpiExOpcode_1A_1T_1R(), AcpiExSystemMemorySpaceHandler(), AcpiGetTimerDuration(), and AcpiUtStrtoulMultiply64().

◆ AcpiUtShortMultiply()

ACPI_STATUS AcpiUtShortMultiply ( UINT64  Multiplicand,
UINT32  Multiplier,
UINT64 OutProduct 
)

Definition at line 88 of file utmath.c.

92{
93 UINT64_OVERLAY MultiplicandOvl;
94 UINT64_OVERLAY Product;
95 UINT32 Carry32;
96
97
98 ACPI_FUNCTION_TRACE (UtShortMultiply);
99
100
101 MultiplicandOvl.Full = Multiplicand;
102
103 /*
104 * The Product is 64 bits, the carry is always 32 bits,
105 * and is generated by the second multiply.
106 */
107 ACPI_MUL_64_BY_32 (0, MultiplicandOvl.Part.Hi, Multiplier,
108 Product.Part.Hi, Carry32);
109
110 ACPI_MUL_64_BY_32 (0, MultiplicandOvl.Part.Lo, Multiplier,
111 Product.Part.Lo, Carry32);
112
113 Product.Part.Hi += Carry32;
114
115 /* Return only what was requested */
116
117 if (OutProduct)
118 {
119 *OutProduct = Product.Full;
120 }
121
123}

Referenced by AcpiUtScanNumber().

◆ AcpiUtShortShiftLeft()

ACPI_STATUS AcpiUtShortShiftLeft ( UINT64  Operand,
UINT32  Count,
UINT64 OutResult 
)

Definition at line 139 of file utmath.c.

143{
144 UINT64_OVERLAY OperandOvl;
145
146
147 ACPI_FUNCTION_TRACE (UtShortShiftLeft);
148
149
150 OperandOvl.Full = Operand;
151
152 if ((Count & 63) >= 32)
153 {
154 OperandOvl.Part.Hi = OperandOvl.Part.Lo;
155 OperandOvl.Part.Lo = 0;
156 Count = (Count & 63) - 32;
157 }
158 ACPI_SHIFT_LEFT_64_BY_32 (OperandOvl.Part.Hi,
159 OperandOvl.Part.Lo, Count);
160
161 /* Return only what was requested */
162
163 if (OutResult)
164 {
165 *OutResult = OperandOvl.Full;
166 }
167
169}
int Count
Definition: noreturn.cpp:7

◆ AcpiUtShortShiftRight()

ACPI_STATUS AcpiUtShortShiftRight ( UINT64  Operand,
UINT32  Count,
UINT64 OutResult 
)

Definition at line 184 of file utmath.c.

188{
189 UINT64_OVERLAY OperandOvl;
190
191
192 ACPI_FUNCTION_TRACE (UtShortShiftRight);
193
194
195 OperandOvl.Full = Operand;
196
197 if ((Count & 63) >= 32)
198 {
199 OperandOvl.Part.Lo = OperandOvl.Part.Hi;
200 OperandOvl.Part.Hi = 0;
201 Count = (Count & 63) - 32;
202 }
203 ACPI_SHIFT_RIGHT_64_BY_32 (OperandOvl.Part.Hi,
204 OperandOvl.Part.Lo, Count);
205
206 /* Return only what was requested */
207
208 if (OutResult)
209 {
210 *OutResult = OperandOvl.Full;
211 }
212
214}

Referenced by AcpiUtHexToAsciiChar().