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 /********************************************************************************** 22 MUL32x32INTO32(A,B,C,ShiftR) 23 C = (A * B) >> ShiftR 24 25 A, B and C are all 32 bit SIGNED numbers and ShiftR can vary from 0 to 64 26 27 The user has to take care that C does not overflow. The result in case 28 of overflow is undefined. 29 30 ***********************************************************************************/ 31 #define MUL32x32INTO32(A, B, C, ShiftR) \ 32 { \ 33 LVM_INT32 MUL32x32INTO32_temp, MUL32x32INTO32_temp2, MUL32x32INTO32_mask, \ 34 MUL32x32INTO32_HH, MUL32x32INTO32_HL, MUL32x32INTO32_LH, MUL32x32INTO32_LL; \ 35 LVM_INT32 shiftValue; \ 36 shiftValue = (ShiftR); \ 37 MUL32x32INTO32_mask = 0x0000FFFF; \ 38 MUL32x32INTO32_HH = ((LVM_INT32)((LVM_INT16)((A) >> 16)) * ((LVM_INT16)((B) >> 16))); \ 39 MUL32x32INTO32_HL = ((LVM_INT32)((B)&MUL32x32INTO32_mask) * ((LVM_INT16)((A) >> 16))); \ 40 MUL32x32INTO32_LH = ((LVM_INT32)((A)&MUL32x32INTO32_mask) * ((LVM_INT16)((B) >> 16))); \ 41 MUL32x32INTO32_LL = \ 42 (LVM_INT32)((A)&MUL32x32INTO32_mask) * (LVM_INT32)((B)&MUL32x32INTO32_mask); \ 43 MUL32x32INTO32_temp = (LVM_INT32)(MUL32x32INTO32_HL & MUL32x32INTO32_mask) + \ 44 (LVM_INT32)(MUL32x32INTO32_LH & MUL32x32INTO32_mask) + \ 45 (LVM_INT32)((MUL32x32INTO32_LL >> 16) & MUL32x32INTO32_mask); \ 46 MUL32x32INTO32_HH = MUL32x32INTO32_HH + (LVM_INT32)(MUL32x32INTO32_HL >> 16) + \ 47 (LVM_INT32)(MUL32x32INTO32_LH >> 16) + \ 48 (LVM_INT32)(MUL32x32INTO32_temp >> 16); \ 49 MUL32x32INTO32_LL = MUL32x32INTO32_LL + (LVM_INT32)(MUL32x32INTO32_HL << 16) + \ 50 (LVM_INT32)(MUL32x32INTO32_LH << 16); \ 51 if (shiftValue < 32) { \ 52 MUL32x32INTO32_HH = MUL32x32INTO32_HH << (32 - shiftValue); \ 53 MUL32x32INTO32_mask = ((LVM_INT32)1 << (32 - shiftValue)) - 1; \ 54 MUL32x32INTO32_LL = (MUL32x32INTO32_LL >> shiftValue) & MUL32x32INTO32_mask; \ 55 MUL32x32INTO32_temp2 = MUL32x32INTO32_HH | MUL32x32INTO32_LL; \ 56 } else { \ 57 MUL32x32INTO32_temp2 = (LVM_INT32)MUL32x32INTO32_HH >> (shiftValue - 32); \ 58 } \ 59 (C) = MUL32x32INTO32_temp2; \ 60 } 61 62 /********************************************************************************** 63 MUL32x16INTO32(A,B,C,ShiftR) 64 C = (A * B) >> ShiftR 65 66 A and C are 32 bit SIGNED numbers. B is a 16 bit SIGNED number. 67 ShiftR can vary from 0 to 48 68 69 The user has to take care that C does not overflow. The result in case 70 of overflow is undefined. 71 72 ***********************************************************************************/ 73 #define MUL32x16INTO32(A, B, C, ShiftR) \ 74 { \ 75 LVM_INT32 MUL32x16INTO32_mask, MUL32x16INTO32_HH, MUL32x16INTO32_LL; \ 76 LVM_INT32 shiftValue; \ 77 shiftValue = (ShiftR); \ 78 MUL32x16INTO32_mask = 0x0000FFFF; \ 79 MUL32x16INTO32_HH = ((LVM_INT32)(B) * ((LVM_INT16)((A) >> 16))); \ 80 MUL32x16INTO32_LL = ((LVM_INT32)((A)&MUL32x16INTO32_mask) * (B)); \ 81 if (shiftValue < 16) { \ 82 MUL32x16INTO32_HH = (LVM_INT32)((LVM_UINT32)MUL32x16INTO32_HH << (16 - shiftValue)); \ 83 (C) = MUL32x16INTO32_HH + (LVM_INT32)(MUL32x16INTO32_LL >> shiftValue); \ 84 } else if (shiftValue < 32) { \ 85 MUL32x16INTO32_HH = (LVM_INT32)(MUL32x16INTO32_HH >> (shiftValue - 16)); \ 86 (C) = MUL32x16INTO32_HH + (LVM_INT32)(MUL32x16INTO32_LL >> shiftValue); \ 87 } else { \ 88 (C) = MUL32x16INTO32_HH >> (shiftValue - 16); \ 89 } \ 90 } 91 92 /********************************************************************************** 93 ADD2_SAT_32x32(A,B,C) 94 C = SAT(A + B) 95 96 A,B and C are 32 bit SIGNED numbers. 97 ***********************************************************************************/ 98 #define ADD2_SAT_32x32(A, B, C) \ 99 { \ 100 (C) = (A) + (B); \ 101 if ((((C) ^ (A)) & ((C) ^ (B))) >> 31) { \ 102 if ((A) < 0) \ 103 (C) = 0x80000000l; \ 104 else \ 105 (C) = 0x7FFFFFFFl; \ 106 } \ 107 } 108 109 #endif /* _LVM_MACROS_H_ */ 110 111 /*** End of file ******************************************************************/ 112