1 /*---------------------------------------------------------------------------*
2 * sh_down.h *
3 * *
4 * Copyright 2007, 2008 Nuance Communciations, Inc. *
5 * *
6 * Licensed under the Apache License, Version 2.0 (the 'License'); *
7 * you may not use this file except in compliance with the License. *
8 * *
9 * You may obtain a copy of the License at *
10 * http://www.apache.org/licenses/LICENSE-2.0 *
11 * *
12 * Unless required by applicable law or agreed to in writing, software *
13 * distributed under the License is distributed on an 'AS IS' BASIS, *
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
15 * See the License for the specific language governing permissions and *
16 * limitations under the License. *
17 * *
18 *---------------------------------------------------------------------------*/
19
20 #ifndef _SH_DOWN_INL_
21 #define _SH_DOWN_INL_
22
23 #include <limits.h>
24
25 #include "fronttyp.h"
26 #include "setting.h"
27 #include "portable.h"
28
29 #define SHIFT_DOWN(X,S) ((S) > 0 ? shift_down_inline ((X), (S)) : (X))
30 #define SHIFT_UP(X,S) ((S) > 0 ? shift_up_inline ((X), (S)) : (X))
31
32 #define COND_SHIFT_DOWN(X,S) (SHIFT_DOWN(X,S))
33 #define COND_SHIFT_UP(X,S) (SHIFT_UP(X,S))
34
35 static PINLINE int fixed_point_convert(float xx, int shift);
36 static PINLINE int shift_up_inline(int value, unsigned int shift);
37 static PINLINE int shift_down_inline(int value, unsigned int shift);
38 static PINLINE int fixed_round(float value);
39
40 #define TRUNCATE_ON_SHIFT 1
41
shift_up_inline(int value,unsigned int shift)42 static PINLINE int shift_up_inline(int value, unsigned int shift)
43 {
44 /* Shift up using bit operations with max limit */
45 int temp, retval;
46
47 ASSERT(shift > 0);
48 if (value > 0)
49 temp = value;
50 else
51 temp = -value;
52
53 retval = temp << shift;
54
55 if ((retval > (int)LONG_MAX) || (retval < temp)) /* TODO: max_val if LONG_MAX, overflow won't be detected */
56 retval = (int)LONG_MAX;
57 if (value > 0)
58 return retval;
59 else
60 return (-retval);
61 }
62
63
shift_down_inline(int value,unsigned int shift)64 static PINLINE int shift_down_inline(int value, unsigned int shift)
65 /* Shift down using bit operations with rounding */
66 {
67 if (shift-- == 0)
68 return (value);
69 if (value >= 0)
70 return (((value >> shift) + 1) >> 1);
71 else
72 return (-((((-value) >> shift) + 1) >> 1));
73 }
74
fixed_point_convert(float xx,int shift)75 static PINLINE int fixed_point_convert(float xx, int shift)
76 {
77 float scaled_val;
78
79 ASSERT(shift >= 0);
80 scaled_val = xx * (0x01 << shift);
81 if (scaled_val >= 0)
82 if (scaled_val > LONG_MAX)
83 return (LONG_MAX);
84 else
85 return ((int)(scaled_val + 0.5));
86 else
87 if (scaled_val < -LONG_MAX)
88 return (-LONG_MAX);
89 else
90 return ((int)(scaled_val - 0.5));
91 }
92
fixed_round(float value)93 static PINLINE int fixed_round(float value)
94 {
95 if (value > 0)
96 return ((int)(value + 0.5));
97 else
98 return ((int)(value - 0.5));
99 }
100
101 #endif
102