[PATCH 08/12] libm: Add support for the Meta architecture

Markos Chandras markos.chandras at gmail.com
Thu Feb 21 10:12:05 UTC 2013


From: Markos Chandras <markos.chandras at imgtec.com>

Signed-off-by: Markos Chandras <markos.chandras at imgtec.com>
---
 libc/sysdeps/linux/metag/bits/fenv.h | 77 ++++++++++++++++++++++++++++++
 libc/sysdeps/linux/metag/metag.c     |  1 +
 libm/metag/Makefile.arch             | 24 ++++++++++
 libm/metag/fclrexcpt.c               | 44 +++++++++++++++++
 libm/metag/fedisblxcpt.c             | 40 ++++++++++++++++
 libm/metag/feenablxcpt.c             | 40 ++++++++++++++++
 libm/metag/fegetenv.c                | 36 ++++++++++++++
 libm/metag/fegetexcept.c             | 31 ++++++++++++
 libm/metag/fegetround.c              | 30 ++++++++++++
 libm/metag/feholdexcpt.c             | 41 ++++++++++++++++
 libm/metag/fesetenv.c                | 60 +++++++++++++++++++++++
 libm/metag/fesetround.c              | 41 ++++++++++++++++
 libm/metag/feupdateenv.c             | 45 ++++++++++++++++++
 libm/metag/fgetexcptflg.c            | 34 +++++++++++++
 libm/metag/fraiseexcpt.c             | 92 ++++++++++++++++++++++++++++++++++++
 libm/metag/fsetexcptflg.c            | 44 +++++++++++++++++
 libm/metag/ftestexcept.c             | 32 +++++++++++++
 libm/metag/internal.h                |  2 +
 18 files changed, 714 insertions(+)
 create mode 100644 libc/sysdeps/linux/metag/bits/fenv.h
 create mode 100644 libm/metag/Makefile.arch
 create mode 100644 libm/metag/fclrexcpt.c
 create mode 100644 libm/metag/fedisblxcpt.c
 create mode 100644 libm/metag/feenablxcpt.c
 create mode 100644 libm/metag/fegetenv.c
 create mode 100644 libm/metag/fegetexcept.c
 create mode 100644 libm/metag/fegetround.c
 create mode 100644 libm/metag/feholdexcpt.c
 create mode 100644 libm/metag/fesetenv.c
 create mode 100644 libm/metag/fesetround.c
 create mode 100644 libm/metag/feupdateenv.c
 create mode 100644 libm/metag/fgetexcptflg.c
 create mode 100644 libm/metag/fraiseexcpt.c
 create mode 100644 libm/metag/fsetexcptflg.c
 create mode 100644 libm/metag/ftestexcept.c
 create mode 100644 libm/metag/internal.h

diff --git a/libc/sysdeps/linux/metag/bits/fenv.h b/libc/sysdeps/linux/metag/bits/fenv.h
new file mode 100644
index 0000000..2794405
--- /dev/null
+++ b/libc/sysdeps/linux/metag/bits/fenv.h
@@ -0,0 +1,77 @@
+/* Copyright (C) 2013 Imagination Technologies Ltd.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _FENV_H
+# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
+#endif
+
+
+/* Define bits representing the exception.  We use the bit positions
+   of the appropriate bits in TXDEFR.  */
+enum
+  {
+    FE_INEXACT = 0x1,
+#define FE_INEXACT	FE_INEXACT
+    FE_UNDERFLOW = 0x2,
+#define FE_UNDERFLOW	FE_UNDERFLOW
+    FE_OVERFLOW = 0x4,
+#define FE_OVERFLOW	FE_OVERFLOW
+    FE_DIVBYZERO = 0x8,
+#define FE_DIVBYZERO	FE_DIVBYZERO
+    FE_INVALID = 0x10,
+#define FE_INVALID	FE_INVALID
+  };
+
+#define FE_ALL_EXCEPT \
+	(FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
+
+/* The Meta FPU supports all of the four defined rounding modes.  We
+   use the values of the rounding mode bits in TXMODE as the values
+   for the appropriate macros.  */
+enum
+  {
+    FE_TONEAREST = 0x0,
+#define FE_TONEAREST	FE_TONEAREST
+    FE_TOWARDZERO = 0x1,
+#define FE_TOWARDZERO	FE_TOWARDZERO
+    FE_UPWARD = 0x2,
+#define FE_UPWARD	FE_UPWARD
+    FE_DOWNWARD = 0x3
+#define FE_DOWNWARD	FE_DOWNWARD
+  };
+
+
+/* Type representing exception flags.  */
+typedef unsigned int fexcept_t;
+
+
+/* Type representing floating-point environment.  */
+typedef struct
+  {
+    unsigned int txdefr;
+    unsigned int txmode;
+  }
+fenv_t;
+
+/* If the default argument is used we use this value.  */
+#define FE_DFL_ENV	((__const fenv_t *) -1)
+
+#ifdef __USE_GNU
+/* Floating-point environment where none of the exception is masked.  */
+# define FE_NOMASK_ENV  ((__const fenv_t *) -2)
+#endif
diff --git a/libc/sysdeps/linux/metag/metag.c b/libc/sysdeps/linux/metag/metag.c
index 6988ec2..fd829ac 100644
--- a/libc/sysdeps/linux/metag/metag.c
+++ b/libc/sysdeps/linux/metag/metag.c
@@ -4,3 +4,4 @@
 #include <sys/syscall.h>
 
 _syscall2(int,metag_setglobalbit,char *,addr,int,mask)
+_syscall1(void,metag_set_fpu_flags,unsigned int,flags)
diff --git a/libm/metag/Makefile.arch b/libm/metag/Makefile.arch
new file mode 100644
index 0000000..1d8b3f8
--- /dev/null
+++ b/libm/metag/Makefile.arch
@@ -0,0 +1,24 @@
+# Makefile for uClibc
+#
+# Copyright (c) 2013 Imagination Technologies Ltd.
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+ifeq ($(UCLIBC_HAS_FENV),y)
+ifeq ($(CONFIG_META_2_1),y)
+libm_ARCH_SRC:=$(wildcard $(libm_ARCH_DIR)/*.c)
+libm_ARCH_OBJ:=$(patsubst $(libm_ARCH_DIR)/%.c,$(libm_ARCH_OUT)/%.o,$(libm_ARCH_SRC))
+CFLAGS-libm += -Wa,-mfpu=metac21
+endif
+endif
+
+libm_ARCH_OBJS:=$(libm_ARCH_OBJ)
+
+ifeq ($(DOPIC),y)
+libm-a-y+=$(libm_ARCH_OBJS:.o=.os)
+else
+libm-a-y+=$(libm_ARCH_OBJS)
+endif
+libm-so-y+=$(libm_ARCH_OBJS:.o=.os)
+
diff --git a/libm/metag/fclrexcpt.c b/libm/metag/fclrexcpt.c
new file mode 100644
index 0000000..10bdc87
--- /dev/null
+++ b/libm/metag/fclrexcpt.c
@@ -0,0 +1,44 @@
+/* Clear given exceptions in current floating-point environment.
+   Copyright (C) 2013 Imagination Technologies Ltd.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+#include <unistd.h>
+
+#include "internal.h"
+
+int
+feclearexcept (int excepts)
+{
+  unsigned int temp;
+
+  /* Get the current exceptions.  */
+  __asm__ ("MOV %0,TXDEFR" : "=r" (temp));
+
+  /* Mask out unsupported bits/exceptions.  */
+  excepts &= FE_ALL_EXCEPT;
+
+  excepts <<= 16;
+
+  temp &= ~excepts;
+
+  metag_set_fpu_flags(temp);
+
+  /* Success.  */
+  return 0;
+}
diff --git a/libm/metag/fedisblxcpt.c b/libm/metag/fedisblxcpt.c
new file mode 100644
index 0000000..07313fa
--- /dev/null
+++ b/libm/metag/fedisblxcpt.c
@@ -0,0 +1,40 @@
+/* Disable floating-point exceptions.
+   Copyright (C) 2013 Imagination Technologies Ltd.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+#include <unistd.h>
+
+#include "internal.h"
+
+int
+fedisableexcept (int excepts)
+{
+  unsigned int old_exc;
+
+  /* Get the current control word.  */
+  __asm__ ("MOV %0,TXDEFR" : "=r" (old_exc));
+
+  old_exc &= FE_ALL_EXCEPT;
+
+  excepts = old_exc & ~excepts;
+
+  metag_set_fpu_flags(excepts);
+
+  return old_exc;
+}
diff --git a/libm/metag/feenablxcpt.c b/libm/metag/feenablxcpt.c
new file mode 100644
index 0000000..8feb964
--- /dev/null
+++ b/libm/metag/feenablxcpt.c
@@ -0,0 +1,40 @@
+/* Enable floating-point exceptions.
+   Copyright (C) 2013 Imagination Technologies Ltd.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+#include <unistd.h>
+
+#include "internal.h"
+
+int
+feenableexcept (int excepts)
+{
+  unsigned int old_exc;
+
+  /* Get the current control word.  */
+  __asm__ ("MOV %0,TXDEFR" : "=r" (old_exc));
+
+  old_exc &= FE_ALL_EXCEPT;
+
+  excepts |= old_exc;
+
+  metag_set_fpu_flags(excepts);
+
+  return old_exc;
+}
diff --git a/libm/metag/fegetenv.c b/libm/metag/fegetenv.c
new file mode 100644
index 0000000..c932514
--- /dev/null
+++ b/libm/metag/fegetenv.c
@@ -0,0 +1,36 @@
+/* Store current floating-point environment.
+   Copyright (C) 2013 Imagination Technologies Ltd.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+
+int
+fegetenv (fenv_t *envp)
+{
+  unsigned int txdefr;
+  unsigned int txmode;
+
+  __asm__ ("MOV %0,TXDEFR" : "=r" (txdefr));
+  __asm__ ("MOV %0,TXMODE" : "=r" (txmode));
+
+  envp->txdefr = txdefr;
+  envp->txmode = txmode;
+
+  /* Success.  */
+  return 0;
+}
diff --git a/libm/metag/fegetexcept.c b/libm/metag/fegetexcept.c
new file mode 100644
index 0000000..8021f6c
--- /dev/null
+++ b/libm/metag/fegetexcept.c
@@ -0,0 +1,31 @@
+/* Get enabled floating-point exceptions.
+   Copyright (C) 2013 Imagination Technologies Ltd.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+
+int
+fegetexcept (void)
+{
+  unsigned int exc;
+
+  /* Get the current control word.  */
+  __asm__ ("MOV %0,TXDEFR" : "=r" (exc));
+
+  return exc & FE_ALL_EXCEPT;
+}
diff --git a/libm/metag/fegetround.c b/libm/metag/fegetround.c
new file mode 100644
index 0000000..1fb5ce2
--- /dev/null
+++ b/libm/metag/fegetround.c
@@ -0,0 +1,30 @@
+/* Return current rounding direction.
+   Copyright (C) 2013 Imagination Technologies Ltd.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+
+int
+fegetround (void)
+{
+  unsigned int txmode;
+
+  __asm__ ("MOV %0,TXMODE" : "=r" (txmode));
+
+  return (txmode >> 16) & 0x3;
+}
diff --git a/libm/metag/feholdexcpt.c b/libm/metag/feholdexcpt.c
new file mode 100644
index 0000000..98ef4d0
--- /dev/null
+++ b/libm/metag/feholdexcpt.c
@@ -0,0 +1,41 @@
+/* Store current floating-point environment and clear exceptions.
+   Copyright (C) 2013 Imagination Technologies Ltd.
+   Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+#include <unistd.h>
+
+#include "internal.h"
+
+int
+feholdexcept (fenv_t *envp)
+{
+  unsigned int txdefr;
+  unsigned int txmode;
+
+  __asm__ ("MOV %0,TXDEFR" : "=r" (txdefr));
+  __asm__ ("MOV %0,TXMODE" : "=r" (txmode));
+
+  envp->txdefr = txdefr;
+  envp->txmode = txmode;
+
+  metag_set_fpu_flags(0);
+
+  return 0;
+}
diff --git a/libm/metag/fesetenv.c b/libm/metag/fesetenv.c
new file mode 100644
index 0000000..7295492
--- /dev/null
+++ b/libm/metag/fesetenv.c
@@ -0,0 +1,60 @@
+/* Install given floating-point environment.
+   Copyright (C) 2013 Imagination Technologies Ltd.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+#include <assert.h>
+
+#include "internal.h"
+
+libm_hidden_proto(fesetenv)
+
+int
+fesetenv (const fenv_t *envp)
+{
+  unsigned int exc;
+  unsigned int txmode;
+
+  __asm__ ("MOV %0,TXMODE" : "=r" (txmode));
+
+  /* Clear rounding mode bits (round to nearest).  */
+  txmode &= ~(0x3 << 16);
+
+  if (envp == FE_DFL_ENV)
+    {
+      exc = 0;
+    }
+  else if (envp == FE_NOMASK_ENV)
+    {
+      exc = 0x1f;
+    }
+  else
+    {
+      exc = envp->txdefr & (FE_ALL_EXCEPT | (FE_ALL_EXCEPT << 16));
+      /* Write rounding mode and guard bit.  */
+      txmode |= (0x1 << 18 ) | (envp->txmode & (0x3 << 16));
+    }
+
+  __asm__ ("MOV TXMODE,%0" : : "r" (txmode));
+
+  metag_set_fpu_flags(exc);
+
+  /* Success.  */
+  return 0;
+}
+libm_hidden_def(fesetenv)
diff --git a/libm/metag/fesetround.c b/libm/metag/fesetround.c
new file mode 100644
index 0000000..2d5b252
--- /dev/null
+++ b/libm/metag/fesetround.c
@@ -0,0 +1,41 @@
+/* Set current rounding direction.
+   Copyright (C) 2013 Imagination Technologies Ltd.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+#include <unistd.h>
+
+int
+fesetround (int round)
+{
+  unsigned int txmode;
+
+  if ((round & ~0x3) != 0)
+    /* ROUND is no valid rounding mode.  */
+    return 1;
+
+  __asm__ ("MOV %0,TXMODE" : "=r" (txmode));
+
+  txmode &= ~(0x3 << 16);
+  /* Write rounding mode and guard bit.  */
+  txmode |= (0x1 << 18 ) | (round << 16);
+
+  __asm__ ("MOV TXMODE,%0" : : "r" (txmode));
+
+  return 0;
+}
diff --git a/libm/metag/feupdateenv.c b/libm/metag/feupdateenv.c
new file mode 100644
index 0000000..f2fc69f
--- /dev/null
+++ b/libm/metag/feupdateenv.c
@@ -0,0 +1,45 @@
+/* Install given floating-point environment and raise exceptions.
+   Copyright (C) 2013 Imagination Technologies Ltd.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+#include <unistd.h>
+
+libm_hidden_proto(fesetenv)
+libm_hidden_proto(feraiseexcept)
+
+int
+feupdateenv (const fenv_t *envp)
+{
+  unsigned int temp;
+
+  /* Save current exceptions.  */
+  __asm__ ("MOV %0,TXDEFR" : "=r" (temp));
+
+  temp >>= 16;
+  temp &= FE_ALL_EXCEPT;
+
+  /* Install new environment.  */
+  fesetenv (envp);
+
+  /* Raise the saved exception.  */
+  feraiseexcept ((int) temp);
+
+  /* Success.  */
+  return 0;
+}
diff --git a/libm/metag/fgetexcptflg.c b/libm/metag/fgetexcptflg.c
new file mode 100644
index 0000000..e1a4bdf
--- /dev/null
+++ b/libm/metag/fgetexcptflg.c
@@ -0,0 +1,34 @@
+/* Store current representation for exceptions.
+   Copyright (C) 2013 Imagination Technologies Ltd.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+
+int
+fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+  unsigned int temp;
+
+  /* Get the current exceptions.  */
+  __asm__ ("MOV %0,TXDEFR" : "=r" (temp));
+
+  *flagp = temp & excepts & FE_ALL_EXCEPT;
+
+  /* Success.  */
+  return 0;
+}
diff --git a/libm/metag/fraiseexcpt.c b/libm/metag/fraiseexcpt.c
new file mode 100644
index 0000000..9ab39bb
--- /dev/null
+++ b/libm/metag/fraiseexcpt.c
@@ -0,0 +1,92 @@
+/* Raise given exceptions.
+   Copyright (C) 2013 Imagination Technologies Ltd.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+#include <math.h>
+
+libm_hidden_proto(feraiseexcept)
+
+int
+feraiseexcept (int excepts)
+{
+  /* Raise exceptions represented by EXPECTS.  But we must raise only
+     one signal at a time.  It is important that if the overflow/underflow
+     exception and the inexact exception are given at the same time,
+     the overflow/underflow exception follows the inexact exception.  */
+
+  /* First: invalid exception.  */
+  if ((FE_INVALID & excepts) != 0)
+    {
+      /* Reciprocal square root of a negative number is invalid. */
+      __asm__ volatile(
+		   "F MOV FX.0,#0xc000 ! -2\n"
+		   "F RSQ FX.1,FX.0\n"
+		   );
+    }
+
+  /* Next: division by zero.  */
+  if ((FE_DIVBYZERO & excepts) != 0)
+    {
+      __asm__ volatile(
+		   "F MOV FX.0,#0\n"
+		   "F RCP FX.1,FX.0\n"
+		   );
+    }
+
+  /* Next: overflow.  */
+  if ((FE_OVERFLOW & excepts) != 0)
+    {
+      /* Adding a large number in single precision can cause overflow. */
+      __asm__ volatile(
+		   "  MOVT D0.0,#0x7f7f\n"
+		   "  ADD  D0.0,D0.0,#0xffff\n"
+		   "F MOV  FX.0,D0.0\n"
+		   "F ADD  FX.1,FX.0,FX.0\n"
+		   );
+    }
+
+  /* Next: underflow.  */
+  if ((FE_UNDERFLOW & excepts) != 0)
+    {
+      /* Multiplying a small value by 0.5 will cause an underflow. */
+      __asm__ volatile(
+		   "  MOV  D0.0,#1\n"
+		   "F MOV  FX.0,D0.0\n"
+		   "  MOVT D0.0,#0x3f00\n"
+		   "F MOV  FX.1,D0.0\n"
+		   "F MUL  FX.2,FX.1,FX.0\n"
+		   );
+    }
+
+  /* Last: inexact.  */
+  if ((FE_INEXACT & excepts) != 0)
+    {
+      /* Converting a small single precision value to half precision
+	 can cause an inexact exception. */
+      __asm__ volatile(
+		   "  MOV  D0.0,#0x0001\n"
+		   "F MOV  FX.0,D0.0\n"
+		   "F FTOH FX.1,FX.0\n"
+		   );
+    }
+
+  /* Success.  */
+  return 0;
+}
+libm_hidden_def(feraiseexcept)
diff --git a/libm/metag/fsetexcptflg.c b/libm/metag/fsetexcptflg.c
new file mode 100644
index 0000000..11ae917
--- /dev/null
+++ b/libm/metag/fsetexcptflg.c
@@ -0,0 +1,44 @@
+/* Set floating-point environment exception handling.
+   Copyright (C) 2013 Imagination Technologies Ltd.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+#include <math.h>
+#include <unistd.h>
+
+#include "internal.h"
+
+int
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+  unsigned int temp;
+
+  /* Get the current exceptions.  */
+  __asm__ ("MOV %0,TXDEFR" : "=r" (temp));
+
+  excepts &= FE_ALL_EXCEPT;
+  excepts <<= 16;
+
+  temp &= ~excepts;
+  temp |= *flagp & excepts;
+
+  metag_set_fpu_flags(temp);
+
+  /* Success.  */
+  return 0;
+}
diff --git a/libm/metag/ftestexcept.c b/libm/metag/ftestexcept.c
new file mode 100644
index 0000000..898630d
--- /dev/null
+++ b/libm/metag/ftestexcept.c
@@ -0,0 +1,32 @@
+/* Test exception in current environment.
+   Copyright (C) 2013 Imagination Technologies Ltd.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+#include <unistd.h>
+
+int
+fetestexcept (int excepts)
+{
+  unsigned int temp;
+
+  /* Get the current exceptions.  */
+  __asm__ ("MOV %0,TXDEFR" : "=r" (temp));
+
+  return (temp >> 16) & excepts & FE_ALL_EXCEPT;
+}
diff --git a/libm/metag/internal.h b/libm/metag/internal.h
new file mode 100644
index 0000000..ebc6d82
--- /dev/null
+++ b/libm/metag/internal.h
@@ -0,0 +1,2 @@
+
+void metag_set_fpu_flags(unsigned int flags);
-- 
1.8.1.2




More information about the uClibc mailing list