1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     math_Misccellaneous.h
4 
5   Copyright (C)2009-2012 Nintendo Co., Ltd.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Rev: 47779 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NN_MATH_MATH_MISCCELLANEOUS_H_
17 #define NN_MATH_MATH_MISCCELLANEOUS_H_
18 
19 #include <nn/types.h>
20 #include <nn/assert.h>
21 
22 #ifdef __cplusplus
23 
24 namespace nn { namespace math {
25 
26     template <u32 MUL, u32 DIV>
27     struct MakeRate
28     {
29         static const u64 VALUE = (static_cast<u64>(MUL) << 32) / DIV;
30         NN_STATIC_ASSERT( (((static_cast<u64>(MUL) << 32) / DIV) >> 32) != 0 );
31     };
32     template <u32 MUL, u32 DIV>
33     struct MakeRate32
34     {
35         static const u32 VALUE = static_cast<u32>( (static_cast<u64>(MUL) << 32) / DIV );
36         NN_STATIC_ASSERT( (((static_cast<u64>(MUL) << 32) / DIV) >> 32) == 0 );
37     };
38 
39 }}  // nn::math
40 
41 #endif // __cplusplus
42 
43 // C declarations follow
44 
45 #include <nn/util/detail/util_CLibImpl.h>
46 
47 
nnmathMultiplyAndDivide(s64 x,s32 mul,s32 div)48 NN_EXTERN_C inline s64 nnmathMultiplyAndDivide(s64 x, s32 mul, s32 div)
49 {
50     // Note right shift
51     // Compiler dependent
52     const s64 rate = ((s64)(mul) << 32) / div;
53     const s32 r_hi = (s32)(rate >> 32);
54     const u32 r_lo = (u32)(rate >>  0);
55     const s32 x_hi = (s32)(x    >> 32);
56     const u32 x_lo = (u32)(x    >>  0);
57 
58     return (((s64)(x_hi) * r_hi) << 32)
59          + ( (s64)(x_hi) * r_lo
60            + (s64)(r_hi) * x_lo )
61          + (((u64)(x_lo) * r_lo) >> 32);
62 }
63 
64 //NN_EXTERN_C inline s64 nnmathArithmeticShiftRightS64(s64 x, int shift)
65 //{
66 //#if (-2 >> 1) == -1
67 //    return x >> shift;
68 //#elif (u64)-1 == 0xFFFFFFFFFFFFFFFFull
69 //    u64 ux   = static_cast<u64>(x);
70 //    u64 uxs  = (ux >> shift);
71 //    u64 us   = - (ux >> 63);
72 //    u64 sign = us << (64 - shift);
73 //    return sign | uxs;
74 //#else
75 //    #error
76 //#endif
77 //}
78 
nnmathMakeRate(u32 mul,u32 div)79 NN_EXTERN_C inline u64 nnmathMakeRate(u32 mul, u32 div)
80 {
81     return ((u64)(mul) << 32) / div;
82 }
nnmathMakeRate32(u32 mul,u32 div)83 NN_EXTERN_C inline u32 nnmathMakeRate32(u32 mul, u32 div)
84 {
85     return (u32)( ((u64)(mul) << 32) / div );
86 }
87 
nnmathMultiplyRate(u64 x,u64 rate)88 NN_EXTERN_C inline u64 nnmathMultiplyRate(u64 x, u64 rate)
89 {
90     const u32 r_hi = (u32)(rate >> 32);
91     const u32 r_lo = (u32)(rate >>  0);
92     const s32 x_hi = (u32)(x    >> 32);
93     const u32 x_lo = (u32)(x    >>  0);
94 
95     return (((u64)(x_hi) * r_hi) << 32)
96          + ( (u64)(x_hi) * r_lo
97            + (u64)(r_hi) * x_lo )
98          + (((u64)(x_lo) * r_lo) >> 32);
99 }
100 
nnmathMultiplyRate32(u64 x,u32 rate)101 NN_EXTERN_C inline u64 nnmathMultiplyRate32(u64 x, u32 rate)
102 {
103     const s32 x_hi = (u32)(x >> 32);
104     const u32 x_lo = (u32)(x >>  0);
105 
106     return   (u64)(x_hi) * rate
107          + (((u64)(x_lo) * rate) >> 32);
108 }
109 
110 
111 #endif // NN_MATH_MATH_MISCCELLANEOUS_H_
112