3 * Copyright (C) 2005-2008 Team XBMC
6 * This Program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * This Program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with XBMC; see the file COPYING. If not, write to
18 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19 * http://www.gnu.org/copyleft/gpl.html
30 // GCC does something stupid with optimization on release builds if we try
31 // to assert in these functions
32 inline int round_int (double x)
34 assert(x > static_cast<double>(INT_MIN / 2) - 1.0);
35 assert(x < static_cast <double>(INT_MAX / 2) + 1.0);
36 const float round_to_nearest = 0.5f;
49 #if defined(__powerpc__) || defined(__ppc__)
50 i = floor(x + round_to_nearest);
51 #elif defined(__arm__)
52 //BIG FIXME here (still has issues with rounding -0.5 to zero and not -1)
53 //the asm codes below do the following - trunc(x+0.5)
54 //this isn't correct for negativ x - values - for example
55 //-1 gets rounded to zero because trunc(-1+0.5) == 0
56 //this is a dirty hack until someone fixes this propably in asm
57 //i've created a trac ticket for this #11767
58 //this hacks decrements the x by 1 if it is negativ
59 // so for -1 it would be trunc(-2+0.5) - which would be correct -1 then ...
62 __asm__ __volatile__ (
63 "vmov.F64 d1,%[rnd_val] \n\t" // Copy round_to_nearest into a working register
64 "vadd.F64 %P[value],%P[value],d1 \n\t" // Add round_to_nearest to value
65 "vcvt.S32.F64 %[result],%P[value] \n\t" // Truncate(round towards zero) and store the result
66 : [result] "=w"(i), [value] "+w"(x) // Outputs
67 : [rnd_val] "Dv" (round_to_nearest) // Inputs
70 __asm__ __volatile__ (
75 : "=m"(i) : "u"(round_to_nearest), "t"(x) : "st"
82 inline int truncate_int(double x)
84 assert(x > static_cast<double>(INT_MIN / 2) - 1.0);
85 assert(x < static_cast <double>(INT_MAX / 2) + 1.0);
87 #if !defined(__powerpc__) && !defined(__ppc__) && !defined(__arm__)
88 const float round_towards_m_i = -0.5f;
98 fadd round_towards_m_i
103 #if defined(__powerpc__) || defined(__ppc__) || defined(__arm__)
106 __asm__ __volatile__ (
112 : "=m"(i) : "u"(round_towards_m_i), "t"(x) : "st"
121 inline int64_t abs(int64_t a)
123 return (a < 0) ? -a : a;
128 // stupid hack to keep compiler from dropping these
129 // functions as unused
130 MathUtils::round_int(0.0);
131 MathUtils::truncate_int(0.0);
134 } // namespace MathUtils