diff gcc/config/arm/fp16.c @ 55:77e2b8dfacca gcc-4.4.5

update it from 4.4.3 to 4.5.0
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Fri, 12 Feb 2010 23:39:51 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gcc/config/arm/fp16.c	Fri Feb 12 23:39:51 2010 +0900
@@ -0,0 +1,145 @@
+/* Half-float conversion routines.
+
+   Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+   Contributed by CodeSourcery.
+
+   This file is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 3, or (at your option) any
+   later version.
+
+   This file is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+static inline unsigned short
+__gnu_f2h_internal(unsigned int a, int ieee)
+{
+  unsigned short sign = (a >> 16) & 0x8000;
+  int aexp = (a >> 23) & 0xff;
+  unsigned int mantissa = a & 0x007fffff;
+  unsigned int mask;
+  unsigned int increment;
+
+  if (aexp == 0xff)
+    {
+      if (!ieee)
+	return sign;
+      return sign | 0x7e00 | (mantissa >> 13);
+    }
+  
+  if (aexp == 0 && mantissa == 0)
+    return sign;
+
+  aexp -= 127;
+
+  /* Decimal point between bits 22 and 23.  */
+  mantissa |= 0x00800000;
+  if (aexp < -14)
+    {
+      mask = 0x007fffff;
+      if (aexp < -25)
+	aexp = -26;
+      else if (aexp != -25)
+	mask >>= 24 + aexp;
+    }
+  else
+    mask = 0x00001fff;
+
+  /* Round.  */
+  if (mantissa & mask)
+    {
+      increment = (mask + 1) >> 1;
+      if ((mantissa & mask) == increment)
+	increment = mantissa & (increment << 1);
+      mantissa += increment;
+      if (mantissa >= 0x01000000)
+       	{
+	  mantissa >>= 1;
+	  aexp++;
+	}
+    }
+
+  if (ieee)
+    {
+      if (aexp > 15)
+	return sign | 0x7c00;
+    }
+  else
+    {
+      if (aexp > 16)
+	return sign | 0x7fff;
+    }
+
+  if (aexp < -24)
+    return sign;
+
+  if (aexp < -14)
+    {
+      mantissa >>= -14 - aexp;
+      aexp = -14;
+    }
+
+  /* We leave the leading 1 in the mantissa, and subtract one
+     from the exponent bias to compensate.  */
+  return sign | (((aexp + 14) << 10) + (mantissa >> 13));
+}
+
+unsigned int
+__gnu_h2f_internal(unsigned short a, int ieee)
+{
+  unsigned int sign = (unsigned int)(a & 0x8000) << 16;
+  int aexp = (a >> 10) & 0x1f;
+  unsigned int mantissa = a & 0x3ff;
+
+  if (aexp == 0x1f && ieee)
+    return sign | 0x7f800000 | (mantissa << 13);
+
+  if (aexp == 0)
+    {
+      int shift;
+
+      if (mantissa == 0)
+	return sign;
+
+      shift = __builtin_clz(mantissa) - 21;
+      mantissa <<= shift;
+      aexp = -shift;
+    }
+
+  return sign | (((aexp + 0x70) << 23) + (mantissa << 13));
+}
+
+unsigned short
+__gnu_f2h_ieee(unsigned int a)
+{
+  return __gnu_f2h_internal(a, 1);
+}
+
+unsigned int
+__gnu_h2f_ieee(unsigned short a)
+{
+  return __gnu_h2f_internal(a, 1);
+}
+
+unsigned short
+__gnu_f2h_alternative(unsigned int x)
+{
+  return __gnu_f2h_internal(x, 0);
+}
+
+unsigned int
+__gnu_h2f_alternative(unsigned short a)
+{
+  return __gnu_h2f_internal(a, 0);
+}