1 /*
2  * Copyright (C) 2004-2010 NXP Software
3  * Copyright (C) 2010 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef _LVM_MACROS_H_
19 #define _LVM_MACROS_H_
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif /* __cplusplus */
24 
25 /**********************************************************************************
26    MUL32x32INTO32(A,B,C,ShiftR)
27         C = (A * B) >> ShiftR
28 
29         A, B and C are all 32 bit SIGNED numbers and ShiftR can vary from 0 to 64
30 
31         The user has to take care that C does not overflow.  The result in case
32         of overflow is undefined.
33 
34 ***********************************************************************************/
35 #ifndef MUL32x32INTO32
36 #define MUL32x32INTO32(A,B,C,ShiftR)   \
37         {LVM_INT32 MUL32x32INTO32_temp,MUL32x32INTO32_temp2,MUL32x32INTO32_mask,MUL32x32INTO32_HH,MUL32x32INTO32_HL,MUL32x32INTO32_LH,MUL32x32INTO32_LL;\
38          LVM_INT32  shiftValue;\
39         shiftValue = (ShiftR);\
40         MUL32x32INTO32_mask=0x0000FFFF;\
41         MUL32x32INTO32_HH= ((LVM_INT32)((LVM_INT16)((A)>>16))*((LVM_INT16)((B)>>16)) );\
42         MUL32x32INTO32_HL= ((LVM_INT32)((B)&MUL32x32INTO32_mask)*((LVM_INT16)((A)>>16))) ;\
43         MUL32x32INTO32_LH= ((LVM_INT32)((A)&MUL32x32INTO32_mask)*((LVM_INT16)((B)>>16)));\
44         MUL32x32INTO32_LL= (LVM_INT32)((A)&MUL32x32INTO32_mask)*(LVM_INT32)((B)&MUL32x32INTO32_mask);\
45         MUL32x32INTO32_temp= (LVM_INT32)(MUL32x32INTO32_HL&MUL32x32INTO32_mask)+(LVM_INT32)(MUL32x32INTO32_LH&MUL32x32INTO32_mask)+(LVM_INT32)((MUL32x32INTO32_LL>>16)&MUL32x32INTO32_mask);\
46         MUL32x32INTO32_HH= MUL32x32INTO32_HH+(LVM_INT32)(MUL32x32INTO32_HL>>16)+(LVM_INT32)(MUL32x32INTO32_LH>>16)+(LVM_INT32)(MUL32x32INTO32_temp>>16);\
47         MUL32x32INTO32_LL=MUL32x32INTO32_LL+(LVM_INT32)(MUL32x32INTO32_HL<<16)+(LVM_INT32)(MUL32x32INTO32_LH<<16);\
48         if(shiftValue<32)\
49         {\
50         MUL32x32INTO32_HH=MUL32x32INTO32_HH<<(32-shiftValue);\
51         MUL32x32INTO32_mask=((LVM_INT32)1<<(32-shiftValue))-1;\
52         MUL32x32INTO32_LL=(MUL32x32INTO32_LL>>shiftValue)&MUL32x32INTO32_mask;\
53         MUL32x32INTO32_temp2=MUL32x32INTO32_HH|MUL32x32INTO32_LL;\
54         }\
55         else\
56        {\
57         MUL32x32INTO32_temp2=(LVM_INT32)MUL32x32INTO32_HH>>(shiftValue-32);\
58        }\
59        (C) = MUL32x32INTO32_temp2;\
60        }
61 #endif
62 
63 /**********************************************************************************
64    MUL32x16INTO32(A,B,C,ShiftR)
65         C = (A * B) >> ShiftR
66 
67         A and C are 32 bit SIGNED numbers.  B is a 16 bit SIGNED number.
68         ShiftR can vary from 0 to 48
69 
70         The user has to take care that C does not overflow.  The result in case
71         of overflow is undefined.
72 
73 ***********************************************************************************/
74 #ifndef MUL32x16INTO32
75 #define MUL32x16INTO32(A,B,C,ShiftR)   \
76         {LVM_INT32 MUL32x16INTO32_mask,MUL32x16INTO32_HH,MUL32x16INTO32_LL;\
77          LVM_INT32  shiftValue;\
78         shiftValue = (ShiftR);\
79         MUL32x16INTO32_mask=0x0000FFFF;\
80         MUL32x16INTO32_HH= ((LVM_INT32)(B)*((LVM_INT16)((A)>>16)));\
81         MUL32x16INTO32_LL= ((LVM_INT32)((A)&MUL32x16INTO32_mask)*(B));\
82         if(shiftValue<16)\
83         {\
84         MUL32x16INTO32_HH=(LVM_INT32)((LVM_UINT32)MUL32x16INTO32_HH<<(16-shiftValue));\
85         (C)=MUL32x16INTO32_HH+(LVM_INT32)(MUL32x16INTO32_LL>>shiftValue);\
86         }\
87         else if(shiftValue<32) {\
88         MUL32x16INTO32_HH=(LVM_INT32)(MUL32x16INTO32_HH>>(shiftValue-16));\
89         (C)=MUL32x16INTO32_HH+(LVM_INT32)(MUL32x16INTO32_LL>>shiftValue);\
90         }\
91         else {\
92         (C)=MUL32x16INTO32_HH>>(shiftValue-16);}\
93         }
94 #endif
95 
96 /**********************************************************************************
97    ADD2_SAT_32x32(A,B,C)
98         C = SAT(A + B)
99 
100         A,B and C are 32 bit SIGNED numbers.
101 ***********************************************************************************/
102 #ifndef ADD2_SAT_32x32
103 #define ADD2_SAT_32x32(A,B,C)   \
104         {(C)=(A)+(B);\
105          if ((((C) ^ (A)) & ((C) ^ (B))) >> 31)\
106             {\
107                 if((A)<0)\
108                     (C)=0x80000000l;\
109                 else\
110                     (C)=0x7FFFFFFFl;\
111             }\
112         }
113 #endif
114 
115 
116 #ifdef __cplusplus
117 }
118 #endif /* __cplusplus */
119 
120 #endif /* _LVM_MACROS_H_ */
121 
122 /*** End of file ******************************************************************/
123