LVM_Macros.h revision 2c8e5cab3faa6d360e222b7a6c40a80083d021ac
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/**********************************************************************************
19
20     $Author: beq07716 $
21     $Revision: 1000 $
22     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $
23
24***********************************************************************************/
25
26#ifndef _LVM_MACROS_H_
27#define _LVM_MACROS_H_
28
29#ifdef __cplusplus
30extern "C" {
31#endif /* __cplusplus */
32
33/**********************************************************************************
34   MUL32x32INTO32(A,B,C,ShiftR)
35        C = (A * B) >> ShiftR
36
37        A, B and C are all 32 bit SIGNED numbers and ShiftR can vary from 0 to 64
38
39        The user has to take care that C does not overflow.  The result in case
40        of overflow is undefined.
41
42***********************************************************************************/
43#ifndef MUL32x32INTO32
44#define MUL32x32INTO32(A,B,C,ShiftR)   \
45        {LVM_INT32 MUL32x32INTO32_temp,MUL32x32INTO32_temp2,MUL32x32INTO32_mask,MUL32x32INTO32_HH,MUL32x32INTO32_HL,MUL32x32INTO32_LH,MUL32x32INTO32_LL;\
46         LVM_INT32  shiftValue;\
47        shiftValue = (ShiftR);\
48        MUL32x32INTO32_mask=0x0000FFFF;\
49        MUL32x32INTO32_HH= ((LVM_INT32)((LVM_INT16)((A)>>16))*((LVM_INT16)((B)>>16)) );\
50        MUL32x32INTO32_HL= ((LVM_INT32)((B)&MUL32x32INTO32_mask)*((LVM_INT16)((A)>>16))) ;\
51        MUL32x32INTO32_LH= ((LVM_INT32)((A)&MUL32x32INTO32_mask)*((LVM_INT16)((B)>>16)));\
52        MUL32x32INTO32_LL= (LVM_INT32)((A)&MUL32x32INTO32_mask)*(LVM_INT32)((B)&MUL32x32INTO32_mask);\
53        MUL32x32INTO32_temp= (LVM_INT32)(MUL32x32INTO32_HL&MUL32x32INTO32_mask)+(LVM_INT32)(MUL32x32INTO32_LH&MUL32x32INTO32_mask)+(LVM_INT32)((MUL32x32INTO32_LL>>16)&MUL32x32INTO32_mask);\
54        MUL32x32INTO32_HH= MUL32x32INTO32_HH+(LVM_INT32)(MUL32x32INTO32_HL>>16)+(LVM_INT32)(MUL32x32INTO32_LH>>16)+(LVM_INT32)(MUL32x32INTO32_temp>>16);\
55        MUL32x32INTO32_LL=MUL32x32INTO32_LL+(LVM_INT32)(MUL32x32INTO32_HL<<16)+(LVM_INT32)(MUL32x32INTO32_LH<<16);\
56        if(shiftValue<32)\
57        {\
58        MUL32x32INTO32_HH=MUL32x32INTO32_HH<<(32-shiftValue);\
59        MUL32x32INTO32_mask=((LVM_INT32)1<<(32-shiftValue))-1;\
60        MUL32x32INTO32_LL=(MUL32x32INTO32_LL>>shiftValue)&MUL32x32INTO32_mask;\
61        MUL32x32INTO32_temp2=MUL32x32INTO32_HH|MUL32x32INTO32_LL;\
62        }\
63        else\
64       {\
65        MUL32x32INTO32_temp2=(LVM_INT32)MUL32x32INTO32_HH>>(shiftValue-32);\
66       }\
67       (C) = MUL32x32INTO32_temp2;\
68       }
69#endif
70
71/**********************************************************************************
72   MUL32x16INTO32(A,B,C,ShiftR)
73        C = (A * B) >> ShiftR
74
75        A and C are 32 bit SIGNED numbers.  B is a 16 bit SIGNED number.
76        ShiftR can vary from 0 to 48
77
78        The user has to take care that C does not overflow.  The result in case
79        of overflow is undefined.
80
81***********************************************************************************/
82#ifndef MUL32x16INTO32
83#define MUL32x16INTO32(A,B,C,ShiftR)   \
84        {LVM_INT32 MUL32x16INTO32_mask,MUL32x16INTO32_HH,MUL32x16INTO32_LL;\
85         LVM_INT32  shiftValue;\
86        shiftValue = (ShiftR);\
87        MUL32x16INTO32_mask=0x0000FFFF;\
88        MUL32x16INTO32_HH= ((LVM_INT32)(B)*((LVM_INT16)((A)>>16)));\
89        MUL32x16INTO32_LL= ((LVM_INT32)((A)&MUL32x16INTO32_mask)*(B));\
90        if(shiftValue<16)\
91        {\
92        MUL32x16INTO32_HH=(LVM_INT32)((LVM_UINT32)MUL32x16INTO32_HH<<(16-shiftValue));\
93        (C)=MUL32x16INTO32_HH+(LVM_INT32)(MUL32x16INTO32_LL>>shiftValue);\
94        }\
95        else if(shiftValue<32) {\
96        MUL32x16INTO32_HH=(LVM_INT32)(MUL32x16INTO32_HH>>(shiftValue-16));\
97        (C)=MUL32x16INTO32_HH+(LVM_INT32)(MUL32x16INTO32_LL>>shiftValue);\
98        }\
99        else {\
100        (C)=MUL32x16INTO32_HH>>(shiftValue-16);}\
101        }
102#endif
103
104/**********************************************************************************
105   ADD2_SAT_32x32(A,B,C)
106        C = SAT(A + B)
107
108        A,B and C are 32 bit SIGNED numbers.
109***********************************************************************************/
110#ifndef ADD2_SAT_32x32
111#define ADD2_SAT_32x32(A,B,C)   \
112        {(C)=(A)+(B);\
113         if ((((C) ^ (A)) & ((C) ^ (B))) >> 31)\
114            {\
115                if((A)<0)\
116                    (C)=0x80000000l;\
117                else\
118                    (C)=0x7FFFFFFFl;\
119            }\
120        }
121#endif
122
123
124#ifdef __cplusplus
125}
126#endif /* __cplusplus */
127
128#endif /* _LVM_MACROS_H_ */
129
130/*** End of file ******************************************************************/
131