fixed_generic_mipsr1.h (4854B)
1 /* Copyright (C) 2007-2009 Xiph.Org Foundation 2 Copyright (C) 2003-2008 Jean-Marc Valin 3 Copyright (C) 2007-2008 CSIRO */ 4 /** 5 @file fixed_generic.h 6 @brief Generic fixed-point operations 7 */ 8 /* 9 Redistribution and use in source and binary forms, with or without 10 modification, are permitted provided that the following conditions 11 are met: 12 13 - Redistributions of source code must retain the above copyright 14 notice, this list of conditions and the following disclaimer. 15 16 - Redistributions in binary form must reproduce the above copyright 17 notice, this list of conditions and the following disclaimer in the 18 documentation and/or other materials provided with the distribution. 19 20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 24 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #ifndef CELT_FIXED_GENERIC_MIPSR1_H 34 #define CELT_FIXED_GENERIC_MIPSR1_H 35 36 #if defined (__mips_dsp) && __mips == 32 37 38 typedef short v2i16 __attribute__((vector_size(4))); 39 typedef char v2i8 __attribute__((vector_size(4))); 40 41 #undef MULT16_32_Q16 42 static inline int MULT16_32_Q16(int a, int b) 43 { 44 long long acc = __builtin_mips_mult(a, b); 45 return __builtin_mips_extr_w(acc, 16); 46 } 47 48 #undef MULT16_32_P16 49 static inline int MULT16_32_P16(int a, int b) 50 { 51 long long acc = __builtin_mips_mult(a, b); 52 return __builtin_mips_extr_r_w(acc, 16); 53 } 54 55 #undef MULT16_32_Q15 56 static inline int MULT16_32_Q15(int a, int b) 57 { 58 long long acc = __builtin_mips_mult(a, b); 59 return __builtin_mips_extr_w(acc, 15); 60 } 61 62 #undef MULT32_32_Q31 63 static inline int MULT32_32_Q31(int a, int b) 64 { 65 long long acc = __builtin_mips_mult(a, b); 66 return __builtin_mips_extr_w(acc, 31); 67 } 68 69 #undef PSHR32 70 static inline int PSHR32(int a, int shift) 71 { 72 return __builtin_mips_shra_r_w(a, shift); 73 } 74 75 #undef MULT16_16_P15 76 static inline int MULT16_16_P15(int a, int b) 77 { 78 int r = a * b; 79 return __builtin_mips_shra_r_w(r, 15); 80 } 81 82 #define OVERRIDE_CELT_MAXABS16 83 static OPUS_INLINE opus_val32 celt_maxabs16(const opus_val16 *x, int len) 84 { 85 int i; 86 v2i16 v2max = (v2i16){ 0, 0 }; 87 v2i16 x01, x23; 88 const v2i16 *x2; 89 opus_val16 maxlo, maxhi; 90 int loops; 91 92 if ((long)x & 2 && len > 0) { 93 v2max = (v2i16){ 0, ABS16(*x) }; 94 x++; 95 len--; 96 } 97 x2 = __builtin_assume_aligned(x, 4); 98 loops = len / 4; 99 100 for (i = 0; i < loops; i++) 101 { 102 x01 = *x2++; 103 x23 = *x2++; 104 x01 = __builtin_mips_absq_s_ph(x01); 105 x23 = __builtin_mips_absq_s_ph(x23); 106 __builtin_mips_cmp_lt_ph(v2max, x01); 107 v2max = __builtin_mips_pick_ph(x01, v2max); 108 __builtin_mips_cmp_lt_ph(v2max, x23); 109 v2max = __builtin_mips_pick_ph(x23, v2max); 110 } 111 112 switch (len & 3) { 113 case 3: 114 x01 = __builtin_mips_absq_s_ph(*x2); 115 __builtin_mips_cmp_lt_ph(v2max, x01); 116 v2max = __builtin_mips_pick_ph(x01, v2max); 117 maxlo = EXTRACT16((opus_val32)v2max); 118 maxhi = EXTRACT16((opus_val32)v2max >> 16); 119 maxlo = MAX16(MAX16(maxlo, maxhi), ABS16(x[len - 1])); 120 break; 121 case 2: 122 x01 = __builtin_mips_absq_s_ph(*x2); 123 __builtin_mips_cmp_lt_ph(v2max, x01); 124 v2max = __builtin_mips_pick_ph(x01, v2max); 125 maxlo = EXTRACT16((opus_val32)v2max); 126 maxhi = EXTRACT16((opus_val32)v2max >> 16); 127 maxlo = MAX16(maxlo, maxhi); 128 break; 129 case 1: 130 maxlo = EXTRACT16((opus_val32)v2max); 131 maxhi = EXTRACT16((opus_val32)v2max >> 16); 132 return MAX16(MAX16(maxlo, maxhi), ABS16(x[len - 1])); 133 break; 134 case 0: 135 maxlo = EXTRACT16((opus_val32)v2max); 136 maxhi = EXTRACT16((opus_val32)v2max >> 16); 137 maxlo = MAX16(maxlo, maxhi); 138 break; 139 default: 140 __builtin_unreachable(); 141 } 142 /* C version might return 0x8000, this one can't 143 * because abs is saturated here. Since result 144 * used only for determine dynamic range 145 * in ilog2-like context it's worth to add 1 146 * for proper magnitude whether saturated 147 */ 148 return (opus_val32)maxlo + 1; 149 } 150 151 #elif __mips == 32 152 153 #undef MULT16_32_Q16 154 #define MULT16_32_Q16(a,b) ((opus_val32)SHR((opus_int64)(SHL32((a), 16))*(b),32)) 155 156 #endif 157 158 #endif /* CELT_FIXED_GENERIC_MIPSR1_H */