• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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