| /* |
| * Copyright (C) 2004-2010 NXP Software |
| * Copyright (C) 2010 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef _LVM_MACROS_H_ |
| #define _LVM_MACROS_H_ |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif /* __cplusplus */ |
| |
| /********************************************************************************** |
| MUL32x32INTO32(A,B,C,ShiftR) |
| C = (A * B) >> ShiftR |
| |
| A, B and C are all 32 bit SIGNED numbers and ShiftR can vary from 0 to 64 |
| |
| The user has to take care that C does not overflow. The result in case |
| of overflow is undefined. |
| |
| ***********************************************************************************/ |
| #ifndef MUL32x32INTO32 |
| #define MUL32x32INTO32(A,B,C,ShiftR) \ |
| {LVM_INT32 MUL32x32INTO32_temp,MUL32x32INTO32_temp2,MUL32x32INTO32_mask,MUL32x32INTO32_HH,MUL32x32INTO32_HL,MUL32x32INTO32_LH,MUL32x32INTO32_LL;\ |
| LVM_INT32 shiftValue;\ |
| shiftValue = (ShiftR);\ |
| MUL32x32INTO32_mask=0x0000FFFF;\ |
| MUL32x32INTO32_HH= ((LVM_INT32)((LVM_INT16)((A)>>16))*((LVM_INT16)((B)>>16)) );\ |
| MUL32x32INTO32_HL= ((LVM_INT32)((B)&MUL32x32INTO32_mask)*((LVM_INT16)((A)>>16))) ;\ |
| MUL32x32INTO32_LH= ((LVM_INT32)((A)&MUL32x32INTO32_mask)*((LVM_INT16)((B)>>16)));\ |
| MUL32x32INTO32_LL= (LVM_INT32)((A)&MUL32x32INTO32_mask)*(LVM_INT32)((B)&MUL32x32INTO32_mask);\ |
| MUL32x32INTO32_temp= (LVM_INT32)(MUL32x32INTO32_HL&MUL32x32INTO32_mask)+(LVM_INT32)(MUL32x32INTO32_LH&MUL32x32INTO32_mask)+(LVM_INT32)((MUL32x32INTO32_LL>>16)&MUL32x32INTO32_mask);\ |
| MUL32x32INTO32_HH= MUL32x32INTO32_HH+(LVM_INT32)(MUL32x32INTO32_HL>>16)+(LVM_INT32)(MUL32x32INTO32_LH>>16)+(LVM_INT32)(MUL32x32INTO32_temp>>16);\ |
| MUL32x32INTO32_LL=MUL32x32INTO32_LL+(LVM_INT32)(MUL32x32INTO32_HL<<16)+(LVM_INT32)(MUL32x32INTO32_LH<<16);\ |
| if(shiftValue<32)\ |
| {\ |
| MUL32x32INTO32_HH=MUL32x32INTO32_HH<<(32-shiftValue);\ |
| MUL32x32INTO32_mask=((LVM_INT32)1<<(32-shiftValue))-1;\ |
| MUL32x32INTO32_LL=(MUL32x32INTO32_LL>>shiftValue)&MUL32x32INTO32_mask;\ |
| MUL32x32INTO32_temp2=MUL32x32INTO32_HH|MUL32x32INTO32_LL;\ |
| }\ |
| else\ |
| {\ |
| MUL32x32INTO32_temp2=(LVM_INT32)MUL32x32INTO32_HH>>(shiftValue-32);\ |
| }\ |
| (C) = MUL32x32INTO32_temp2;\ |
| } |
| #endif |
| |
| /********************************************************************************** |
| MUL32x16INTO32(A,B,C,ShiftR) |
| C = (A * B) >> ShiftR |
| |
| A and C are 32 bit SIGNED numbers. B is a 16 bit SIGNED number. |
| ShiftR can vary from 0 to 48 |
| |
| The user has to take care that C does not overflow. The result in case |
| of overflow is undefined. |
| |
| ***********************************************************************************/ |
| #ifndef MUL32x16INTO32 |
| #define MUL32x16INTO32(A,B,C,ShiftR) \ |
| {LVM_INT32 MUL32x16INTO32_mask,MUL32x16INTO32_HH,MUL32x16INTO32_LL;\ |
| LVM_INT32 shiftValue;\ |
| shiftValue = (ShiftR);\ |
| MUL32x16INTO32_mask=0x0000FFFF;\ |
| MUL32x16INTO32_HH= ((LVM_INT32)(B)*((LVM_INT16)((A)>>16)));\ |
| MUL32x16INTO32_LL= ((LVM_INT32)((A)&MUL32x16INTO32_mask)*(B));\ |
| if(shiftValue<16)\ |
| {\ |
| MUL32x16INTO32_HH=(LVM_INT32)((LVM_UINT32)MUL32x16INTO32_HH<<(16-shiftValue));\ |
| (C)=MUL32x16INTO32_HH+(LVM_INT32)(MUL32x16INTO32_LL>>shiftValue);\ |
| }\ |
| else if(shiftValue<32) {\ |
| MUL32x16INTO32_HH=(LVM_INT32)(MUL32x16INTO32_HH>>(shiftValue-16));\ |
| (C)=MUL32x16INTO32_HH+(LVM_INT32)(MUL32x16INTO32_LL>>shiftValue);\ |
| }\ |
| else {\ |
| (C)=MUL32x16INTO32_HH>>(shiftValue-16);}\ |
| } |
| #endif |
| |
| /********************************************************************************** |
| ADD2_SAT_32x32(A,B,C) |
| C = SAT(A + B) |
| |
| A,B and C are 32 bit SIGNED numbers. |
| ***********************************************************************************/ |
| #ifndef ADD2_SAT_32x32 |
| #define ADD2_SAT_32x32(A,B,C) \ |
| {(C)=(A)+(B);\ |
| if ((((C) ^ (A)) & ((C) ^ (B))) >> 31)\ |
| {\ |
| if((A)<0)\ |
| (C)=0x80000000l;\ |
| else\ |
| (C)=0x7FFFFFFFl;\ |
| }\ |
| } |
| #endif |
| |
| |
| #ifdef __cplusplus |
| } |
| #endif /* __cplusplus */ |
| |
| #endif /* _LVM_MACROS_H_ */ |
| |
| /*** End of file ******************************************************************/ |