blob: ec38459791dba8df5fe4a07db5f5b465f236d5ec [file] [log] [blame]
/*---------------------------------------------------------------------------*
* sh_down.h *
* *
* Copyright 2007, 2008 Nuance Communciations, Inc. *
* *
* 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 _SH_DOWN_INL_
#define _SH_DOWN_INL_
#include <limits.h>
#include "fronttyp.h"
#include "setting.h"
#include "portable.h"
#define SHIFT_DOWN(X,S) ((S) > 0 ? shift_down_inline ((X), (S)) : (X))
#define SHIFT_UP(X,S) ((S) > 0 ? shift_up_inline ((X), (S)) : (X))
#define COND_SHIFT_DOWN(X,S) (SHIFT_DOWN(X,S))
#define COND_SHIFT_UP(X,S) (SHIFT_UP(X,S))
static PINLINE int fixed_point_convert(float xx, int shift);
static PINLINE int shift_up_inline(int value, unsigned int shift);
static PINLINE int shift_down_inline(int value, unsigned int shift);
static PINLINE int fixed_round(float value);
#define TRUNCATE_ON_SHIFT 1
static PINLINE int shift_up_inline(int value, unsigned int shift)
{
/* Shift up using bit operations with max limit */
int temp, retval;
ASSERT(shift > 0);
if (value > 0)
temp = value;
else
temp = -value;
retval = temp << shift;
if ((retval > (int)LONG_MAX) || (retval < temp)) /* TODO: max_val if LONG_MAX, overflow won't be detected */
retval = (int)LONG_MAX;
if (value > 0)
return retval;
else
return (-retval);
}
static PINLINE int shift_down_inline(int value, unsigned int shift)
/* Shift down using bit operations with rounding */
{
if (shift-- == 0)
return (value);
if (value >= 0)
return (((value >> shift) + 1) >> 1);
else
return (-((((-value) >> shift) + 1) >> 1));
}
static PINLINE int fixed_point_convert(float xx, int shift)
{
float scaled_val;
ASSERT(shift >= 0);
scaled_val = xx * (0x01 << shift);
if (scaled_val >= 0)
if (scaled_val > INT_MAX)
return (INT_MAX);
else
return ((int)(scaled_val + 0.5));
else
if (scaled_val < -INT_MAX)
return (-INT_MAX);
else
return ((int)(scaled_val - 0.5));
}
static PINLINE int fixed_round(float value)
{
if (value > 0)
return ((int)(value + 0.5));
else
return ((int)(value - 0.5));
}
#endif