git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			376 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			376 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*++
 | |
| 
 | |
| Copyright (c) 2006, Intel Corporation                                                         
 | |
| All rights reserved. This program and the accompanying materials                          
 | |
| are licensed and made available under the terms and conditions of the BSD License         
 | |
| which accompanies this distribution.  The full text of the license may be found at        
 | |
| http://opensource.org/licenses/bsd-license.php                                            
 | |
|                                                                                           
 | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
 | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
 | |
| 
 | |
| Module Name:
 | |
| 
 | |
|   Ipfmath.c
 | |
| 
 | |
| Abstract:
 | |
| 
 | |
|   Math routines for IPF.
 | |
| 
 | |
| --*/
 | |
| 
 | |
| UINT64
 | |
| LeftShiftU64 (
 | |
|   IN UINT64   Operand,
 | |
|   IN UINT64   Count
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
|   
 | |
|   Left-shift a 64 bit value.
 | |
| 
 | |
| Arguments:
 | |
| 
 | |
|   Operand - 64-bit value to shift
 | |
|   Count   - shift count
 | |
| 
 | |
| Returns:
 | |
| 
 | |
|   Operand << Count
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   if (Count > 63) {
 | |
|     return 0;
 | |
|   }
 | |
| 
 | |
|   return Operand << Count;
 | |
| }
 | |
| 
 | |
| UINT64
 | |
| RightShiftU64 (
 | |
|   IN UINT64   Operand,
 | |
|   IN UINT64   Count
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
|   
 | |
|   Right-shift a 64 bit value.
 | |
| 
 | |
| Arguments:
 | |
| 
 | |
|   Operand - 64-bit value to shift
 | |
|   Count   - shift count
 | |
| 
 | |
| Returns:
 | |
| 
 | |
|   Operand >> Count
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   if (Count > 63) {
 | |
|     return 0;
 | |
|   }
 | |
| 
 | |
|   return Operand >> Count;
 | |
| }
 | |
| 
 | |
| INT64
 | |
| ARightShift64 (
 | |
|   IN INT64   Operand,
 | |
|   IN UINT64  Count
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
|   
 | |
|   Right-shift a 64 bit signed value.
 | |
| 
 | |
| Arguments:
 | |
| 
 | |
|   Operand - 64-bit value to shift
 | |
|   Count   - shift count
 | |
| 
 | |
| Returns:
 | |
| 
 | |
|   Operand >> Count
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   if (Count > 63) {
 | |
| 
 | |
|     if (Operand & (0x01 << 63)) {
 | |
|       return (INT64)~0;
 | |
|     }
 | |
| 
 | |
|     return 0;
 | |
|   }
 | |
| 
 | |
|   return Operand >> Count;
 | |
| }
 | |
| 
 | |
| #if 0
 | |
| //
 | |
| // The compiler generates true assembly for these, so we don't need them.
 | |
| //
 | |
| INT32
 | |
| ARightShift32 (
 | |
|   IN INT32   Operand,
 | |
|   IN UINTN   Count
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
|   
 | |
|   Right shift a 32-bit value
 | |
| 
 | |
| Arguments:
 | |
| 
 | |
|   Operand - value to shift
 | |
|   Count   - shift count
 | |
| 
 | |
| Returns:
 | |
| 
 | |
|   Operand >> Count
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   return Operand >> (Count & 0x1f);
 | |
| }
 | |
| 
 | |
| INT32
 | |
| MulS32x32 (
 | |
|   INT32 Value1,
 | |
|   INT32 Value2,
 | |
|   INT32 *ResultHigh
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
|   
 | |
|   Multiply two signed 32-bit numbers.
 | |
| 
 | |
| Arguments:
 | |
| 
 | |
|   Value1      - first value to multiply
 | |
|   Value2      - value to multiply Value1 by
 | |
|   ResultHigh  - overflow
 | |
| 
 | |
| Returns:
 | |
| 
 | |
|   Value1 * Value2
 | |
| 
 | |
| Notes:
 | |
| 
 | |
|   The 64-bit result is the concatenation of *ResultHigh and the return value
 | |
| 
 | |
|   The product fits in 32 bits if
 | |
|      (*ResultHigh == 0x00000000 AND *ResultLow_bit31 == 0)
 | |
|                                      OR
 | |
|      (*ResultHigh == 0xffffffff AND *ResultLow_bit31 == 1)
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   INT64 Rres64;
 | |
|   INT32 Result;
 | |
| 
 | |
|   Res64       = (INT64) Value1 * (INT64) Value2;
 | |
|   *ResultHigh = (Res64 >> 32) & 0xffffffff;
 | |
|   Result      = Res64 & 0xffffffff;
 | |
|   return Result;
 | |
| }
 | |
| 
 | |
| UINT32
 | |
| MulU32x32 (
 | |
|   UINT32 Value1,
 | |
|   UINT32 Value2,
 | |
|   UINT32 *ResultHigh
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
|   
 | |
|   Multiply two unsigned 32-bit values.
 | |
| 
 | |
| Arguments:
 | |
| 
 | |
|   Value1      - first number
 | |
|   Value2      - number to multiply by Value1 
 | |
|   ResultHigh  - overflow
 | |
| 
 | |
| Returns:
 | |
| 
 | |
|   Value1 * Value2
 | |
| 
 | |
| Notes:
 | |
| 
 | |
|   The 64-bit result is the concatenation of *ResultHigh and the return value.
 | |
|   The product fits in 32 bits if *ResultHigh == 0x00000000
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   UINT64  Res64;
 | |
|   UINT32  Result;
 | |
| 
 | |
|   Res64       = (INT64) Value1 * (INT64) Value2;
 | |
|   *ResultHigh = (Res64 >> 32) & 0xffffffff;
 | |
|   Result      = Res64 & 0xffffffff;
 | |
|   return Result;
 | |
| }
 | |
| 
 | |
| INT32
 | |
| DivS32x32 (
 | |
|   INT32 Value1,
 | |
|   INT32 Value2,
 | |
|   INT32 *Remainder,
 | |
|   UINTN *error
 | |
|   )
 | |
| //
 | |
| // signed 32-bit by signed 32-bit divide; the 32-bit remainder is
 | |
| // in *Remainder and the quotient is the return value; *error = 1 if the
 | |
| // divisor is 0, and it is 1 otherwise
 | |
| //
 | |
| {
 | |
|   INT32 Result;
 | |
| 
 | |
|   *error = 0;
 | |
| 
 | |
|   if (Value2 == 0x0) {
 | |
|     *error      = 1;
 | |
|     Result      = 0x80000000;
 | |
|     *Remainder  = 0x80000000;
 | |
|   } else {
 | |
|     Result      = Value1 / Value2;
 | |
|     *Remainder  = Value1 - Result * Value2;
 | |
|   }
 | |
| 
 | |
|   return Result;
 | |
| }
 | |
| 
 | |
| UINT32
 | |
| DivU32x32 (
 | |
|   UINT32  Value1,
 | |
|   UINT32  Value2,
 | |
|   UINT32  *Remainder,
 | |
|   UINTN   *Error
 | |
|   )
 | |
| //
 | |
| // unsigned 32-bit by unsigned 32-bit divide; the 32-bit remainder is
 | |
| // in *Remainder and the quotient is the return value; *error = 1 if the
 | |
| // divisor is 0, and it is 1 otherwise
 | |
| //
 | |
| {
 | |
|   UINT32  Result;
 | |
| 
 | |
|   *Error = 0;
 | |
| 
 | |
|   if (Value2 == 0x0) {
 | |
|     *Error      = 1;
 | |
|     Result      = 0x80000000;
 | |
|     *Remainder  = 0x80000000;
 | |
|   } else {
 | |
|     Result      = Value1 / Value2;
 | |
|     *Remainder  = Value1 - Result * Value2;
 | |
|   }
 | |
| 
 | |
|   return Result;
 | |
| }
 | |
| 
 | |
| #endif
 | |
| 
 | |
| INT64
 | |
| DivS64x64 (
 | |
|   INT64 Value1,
 | |
|   INT64 Value2,
 | |
|   INT64 *Remainder,
 | |
|   UINTN *Error
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
|   
 | |
|   Divide two 64-bit signed values.
 | |
| 
 | |
| Arguments:
 | |
| 
 | |
|   Value1    - dividend
 | |
|   Value2    - divisor
 | |
|   Remainder - remainder of Value1/Value2
 | |
|   Error     - to flag errors (divide-by-0)
 | |
| 
 | |
| Returns:
 | |
| 
 | |
|   Value1 / Valu2
 | |
| 
 | |
| Note:
 | |
| 
 | |
|   The 64-bit remainder is in *Remainder and the quotient is the return value.
 | |
|   *Error = 1 if the divisor is 0, and it is 1 otherwise
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   INT64 Result;
 | |
| 
 | |
|   *Error = 0;
 | |
| 
 | |
|   if (Value2 == 0x0) {
 | |
|     *Error      = 1;
 | |
|     Result      = 0x8000000000000000;
 | |
|     *Remainder  = 0x8000000000000000;
 | |
|   } else {
 | |
|     Result      = Value1 / Value2;
 | |
|     *Remainder  = Value1 - Result * Value2;
 | |
|   }
 | |
| 
 | |
|   return Result;
 | |
| }
 | |
| 
 | |
| UINT64
 | |
| DivU64x64 (
 | |
|   UINT64 Value1,
 | |
|   UINT64 Value2,
 | |
|   UINT64 *Remainder,
 | |
|   UINTN  *Error
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
|   
 | |
|   Divide two 64-bit unsigned values.
 | |
| 
 | |
| Arguments:
 | |
| 
 | |
|   Value1    - dividend
 | |
|   Value2    - divisor
 | |
|   Remainder - remainder of Value1/Value2
 | |
|   Error     - to flag errors (divide-by-0)
 | |
| 
 | |
| Returns:
 | |
| 
 | |
|   Value1 / Valu2
 | |
| 
 | |
| Note:
 | |
| 
 | |
|   The 64-bit remainder is in *Remainder and the quotient is the return value.
 | |
|   *Error = 1 if the divisor is 0, and it is 1 otherwise
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   UINT64  Result;
 | |
| 
 | |
|   *Error = 0;
 | |
| 
 | |
|   if (Value2 == 0x0) {
 | |
|     *Error      = 1;
 | |
|     Result      = 0x8000000000000000;
 | |
|     *Remainder  = 0x8000000000000000;
 | |
|   } else {
 | |
|     Result      = Value1 / Value2;
 | |
|     *Remainder  = Value1 - Result * Value2;
 | |
|   }
 | |
| 
 | |
|   return Result;
 | |
| }
 |