Home | History | Annotate | Download | only in lib
      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