/*---------------------------------------------------------------------------* Project: TwlSDK - MATH - include File: math/math.h Copyright 2003-2008 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Date:: $ $Rev:$ $Author:$ *---------------------------------------------------------------------------*/ #ifndef NITRO_MATH_MATH_H_ #define NITRO_MATH_MATH_H_ #include #include #ifdef __cplusplus extern "C" { #endif //---------------------------------------------------------------------------- // Type Definitions //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Function Declarations //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Inline Function Implementation //---------------------------------------------------------------------------- /*---------------------------------------------------------------------------* Name: MATH_ABS Description: Macro that returns absolute value. Be careful about side effects, since each argument is subjected to multiple valuations. Arguments: a Returns: If a < 0 -a. Otherwise, a *---------------------------------------------------------------------------*/ #define MATH_ABS(a) ( ( (a) < 0 ) ? (-(a)) : (a) ) /*---------------------------------------------------------------------------* Name: MATH_IAbs Description: Inline function that returns absolute value. Since this is implemented as an inline function, there are no side effects. Arguments: a Returns: If a < 0 -a. Otherwise, a *---------------------------------------------------------------------------*/ SDK_INLINE int MATH_IAbs(int a) { return (a < 0) ? -a : a; } /*---------------------------------------------------------------------------* Name: MATH_CLAMP Description: Macro that gets values in the range from "low" to "high." Be careful about side effects, since each argument is subjected to multiple valuations. Arguments: x low: Maximum value hight: Minimum value Returns: If x < low, low. If x > high, high. Otherwise x. *---------------------------------------------------------------------------*/ #define MATH_CLAMP(x, low, high) ( ( (x) > (high) ) ? (high) : ( ( (x) < (low) ) ? (low) : (x) ) ) /*---------------------------------------------------------------------------* Name: MATH_MIN Description: Compares two arguments and returns the smaller one. This is implemented as a macro, so it can be used in the type that defines the inequality operator. Be careful about side effects, since each argument is subjected to multiple valuations. Arguments: a, b Returns: If a < b, a. Otherwise, b. *---------------------------------------------------------------------------*/ #define MATH_MIN(a,b) (((a) <= (b)) ? (a) : (b)) /*---------------------------------------------------------------------------* Name: MATH_IMin Description: Compares two int-type integer arguments and returns the smaller one. Since this is implemented as an inline function, there are no side effects. Arguments: a, b: int type integers Returns: If a <= b, a. Otherwise, b. *---------------------------------------------------------------------------*/ SDK_INLINE int MATH_IMin(int a, int b) { return (a <= b) ? a : b; } /*---------------------------------------------------------------------------* Name: MATH_MAX Description: Compares two arguments and returns the larger one. This is implemented as a macro, so it can be used in the type that defines the inequality operator. Be careful about side effects, since each argument is subjected to multiple valuations. Arguments: a, b Returns: If a >= b, a. Otherwise, b. *---------------------------------------------------------------------------*/ #define MATH_MAX(a,b) (((a) >= (b)) ? (a) : (b)) /*---------------------------------------------------------------------------* Name: MATH_IMax Description: Compares two int-type integer arguments and returns the larger one. Since this is implemented as an inline function, there are no side effects. Arguments: a, b: int type integers Returns: If a >= b, a. Otherwise, b. *---------------------------------------------------------------------------*/ SDK_INLINE int MATH_IMax(int a, int b) { return (a >= b) ? a : b; } /*---------------------------------------------------------------------------* Name: MATH_DIVUP Description: This macro divides by base and takes the ceiling of the result. Arguments: x: Numeric value base: Base that is a power of 2 Returns: A number that is the result of dividing x by base and taking the ceiling of the quotient. *---------------------------------------------------------------------------*/ #define MATH_DIVUP(x, base) (((x) + ((base)-1)) / (base)) /*---------------------------------------------------------------------------* Name: MATH_ROUNDUP Description: Macro that returns the rounded-up value (ceiling). Arguments: x base: Base of the power of 2 Returns: Smallest multiple of "base" that is greater than or equal to x *---------------------------------------------------------------------------*/ #define MATH_ROUNDUP(x, base) (((x) + ((base)-1)) & ~((base)-1)) /*---------------------------------------------------------------------------* Name: MATH_ROUNDDOWN Description: Macro that returns the rounded-down value (floor). Arguments: x base: Base of the power of 2 Returns: Largest multiple of "base" that is less than or equal to x *---------------------------------------------------------------------------*/ #define MATH_ROUNDDOWN(x, base) ((x) & ~((base)-1)) /*---------------------------------------------------------------------------* Name: MATH_ROUNDUP32 Description: Macro that returns the value rounded-up to a multiple of 32. Arguments: x Returns: Smallest multiple of 32 that is greater than or equal to x *---------------------------------------------------------------------------*/ #define MATH_ROUNDUP32(x) MATH_ROUNDUP(x, 32) /*---------------------------------------------------------------------------* Name: MATH_ROUNDDOWN32 Description: Macro that returns the value rounded-down to a multiple of 32. Arguments: x Returns: Largest multiple of 32 that is less than or equal to x *---------------------------------------------------------------------------*/ #define MATH_ROUNDDOWN32(x) MATH_ROUNDDOWN(x, 32) /*---------------------------------------------------------------------------* Name: MATH_CountLeadingZeros Description: Determines how many bits from the top have the value 0 in a binary 32-bit expression. In the ARM9 ARM code, this is a single command. Arguments: x Returns: The number of contiguous 0 bits from the top *---------------------------------------------------------------------------*/ u32 MATH_CountLeadingZerosFunc(u32 x); #if !defined(PLATFORM_INTRINSIC_FUNCTION_BIT_CLZ32) /* clz is available in ARM mode only */ #ifdef SDK_ARM9 #if defined(SDK_CW) || defined(SDK_RX) || defined(__MWERKS__) #pragma thumb off SDK_INLINE u32 MATH_CountLeadingZerosInline(u32 x) { asm { clz x, x} return x; } #pragma thumb reset #elif defined(SDK_ADS) TO BE DEFINED #elif defined(SDK_GCC) TO BE DEFINED #endif #endif #endif /* PLATFORM_INTRINSIC_FUNCTION_BIT_CLZ32 */ #ifndef MATH_CountLeadingZeros #if defined(PLATFORM_INTRINSIC_FUNCTION_BIT_CLZ32) #define MATH_CountLeadingZeros(x) PLATFORM_INTRINSIC_FUNCTION_BIT_CLZ32(x) #elif defined(SDK_ARM9) && defined(SDK_CODE_ARM) #define MATH_CountLeadingZeros(x) MATH_CountLeadingZerosInline(x) #else // not (ARM9 && CODE_ARM) #define MATH_CountLeadingZeros(x) MATH_CountLeadingZerosFunc(x) #endif // ARM9 && CODE_ARM #endif /*---------------------------------------------------------------------------* Name: MATH_CLZ Description: This is MATH_CountLeadingZeros under a different name. Determines how many bits from the top have the value 0 in a binary 32-bit expression. In the ARM9 ARM code, this is a single command. Arguments: x Returns: The number of contiguous 0 bits from the top *---------------------------------------------------------------------------*/ #define MATH_CLZ(x) MATH_CountLeadingZeros(x) /*---------------------------------------------------------------------------* Name: MATH_ILog2 Description: Gets the integer portion of the base-2 logarithm log2(x) of the u32 x argument. In the special case where x == 0, the function returns -1. In the ARM9 ARM code, this is two commands using the CLZ command. Arguments: x: u32 Returns: log2(x) when x > 0, or -1 when x == 0 *---------------------------------------------------------------------------*/ SDK_INLINE int MATH_ILog2(u32 x) { return (int)(31 - MATH_CountLeadingZeros(x)); } /*---------------------------------------------------------------------------* Name: MATH_CountPopulation Description: Determines the number of '1' bits in a binary 32-bit expression. Arguments: x Returns: The number of '1' bits in the binary expression *---------------------------------------------------------------------------*/ u8 MATH_CountPopulation(u32 x); /*---------------------------------------------------------------------------* Name: MATH_CountTrailingZeros Description: Determines how many bits from the bottom have the value 0 in a binary 32-bit expression. Uses the MATH_CountLeadingZeros function. Arguments: x: u32 value used for determination Returns: The number of contiguous 0 bits from the lower bit. *---------------------------------------------------------------------------*/ SDK_INLINE u32 MATH_CountTrailingZeros(u32 x) { return (u32)(32 - MATH_CountLeadingZeros((u32)(~x & (x - 1)))); } /*---------------------------------------------------------------------------* Name: MATH_CTZ Description: This is MATH_CountTrailingZeros under a different name. Determines how many bits from the bottom have the value 0 in a binary 32-bit expression. Uses the MATH_CountLeadingZeros function. Arguments: x: u32 value used for determination Returns: The number of contiguous 0 bits from the lower bit. *---------------------------------------------------------------------------*/ #define MATH_CTZ(x) MATH_CountTrailingZeros(x) /*---------------------------------------------------------------------------* Name: MATH_GetLeastSignificantBit Description: Determines the lowest '1' bit in a binary 32bit expression. Arguments: x: u32 value used for determination Returns: A u32 value expressing the lowest '1' bit. *---------------------------------------------------------------------------*/ SDK_INLINE u32 MATH_GetLeastSignificantBit(u32 x) { return (u32)(x & -(s32)x); } /*---------------------------------------------------------------------------* Name: MATH_LSB Description: Another name for MATH_GetLeastSignificantBit. Determines the lowest '1' bit in a binary 32-bit expression. Arguments: x: u32 value used for determination Returns: A u32 value expressing the lowest '1' bit. *---------------------------------------------------------------------------*/ #define MATH_LSB(x) MATH_GetLeastSignificantBit(x) /*---------------------------------------------------------------------------* Name: MATH_GetMostSignificantBit Description: Determines the highest '1' bit in a binary 32-bit expression. Arguments: x: u32 value used for determination Returns: A u32 value expressing the topmost '1' bit. *---------------------------------------------------------------------------*/ SDK_INLINE u32 MATH_GetMostSignificantBit(u32 x) { return (u32)(x & ((s32)0x80000000 >> MATH_CountLeadingZeros(x))); } /*---------------------------------------------------------------------------* Name: MATH_MSB Description: Another name for MATH_GetMostSignificantBit. Determines the highest '1' bit in a binary 32-bit expression. Arguments: x: u32 value used for determination Returns: A u32 value expressing the highest '1' bit. *---------------------------------------------------------------------------*/ #define MATH_MSB(x) MATH_GetMostSignificantBit(x) #ifdef __cplusplus }/* extern "C" */ #endif /* NITRO_MATH_MATH_H_ */ #endif