ReactOS  0.4.14-dev-1007-g90d795b
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 }
UINT64_STRUCT Part
Definition: utmath.c:63
#define ACPI_SHIFT_RIGHT_64(n_hi, n_lo)
Definition: acos2.h:84
unsigned int UINT32
#define AE_INFO
Definition: acoutput.h:230
UINT64 Full
Definition: utmath.c:62
UINT32 Hi
Definition: utmath.c:56
UINT32 Lo
Definition: utmath.c:55
#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
_In_ LARGE_INTEGER Divisor
Definition: rtlfuncs.h:3046
signed int INT32
unsigned long long UINT64
#define AE_AML_DIVIDE_BY_ZERO
Definition: acexcep.h:191
#define AE_OK
Definition: acexcep.h:97
_In_ LARGE_INTEGER _Out_opt_ PLARGE_INTEGER Remainder
Definition: rtlfuncs.h:3046

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 }
UINT64_STRUCT Part
Definition: utmath.c:63
unsigned int UINT32
#define AE_INFO
Definition: acoutput.h:230
UINT64 Full
Definition: utmath.c:62
UINT32 Hi
Definition: utmath.c:56
UINT32 Lo
Definition: utmath.c:55
#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
_In_ LARGE_INTEGER Divisor
Definition: rtlfuncs.h:3046
#define AE_AML_DIVIDE_BY_ZERO
Definition: acexcep.h:191
#define AE_OK
Definition: acexcep.h:97

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 }
UINT64_STRUCT Part
Definition: utmath.c:63
unsigned int UINT32
UINT64 Full
Definition: utmath.c:62
UINT32 Hi
Definition: utmath.c:56
UINT32 Lo
Definition: utmath.c:55
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
#define AE_OK
Definition: acexcep.h:97

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 }
UINT64_STRUCT Part
Definition: utmath.c:63
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
UINT64 Full
Definition: utmath.c:62
UINT32 Hi
Definition: utmath.c:56
UINT32 Lo
Definition: utmath.c:55
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
#define AE_OK
Definition: acexcep.h:97

◆ 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 }
UINT64_STRUCT Part
Definition: utmath.c:63
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
UINT64 Full
Definition: utmath.c:62
UINT32 Hi
Definition: utmath.c:56
UINT32 Lo
Definition: utmath.c:55
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
#define AE_OK
Definition: acexcep.h:97

Referenced by AcpiUtHexToAsciiChar().