diff options
author | Ben Cheng <bccheng@google.com> | 2012-10-01 10:30:31 -0700 |
---|---|---|
committer | Ben Cheng <bccheng@google.com> | 2012-10-01 10:30:31 -0700 |
commit | 82bcbebce43f0227f506d75a5b764b6847041bae (patch) | |
tree | fe9f8597b48a430c4daeb5123e3e8eb28e6f9da9 /gcc-4.7/libgo/runtime/go-matherr.c | |
parent | 3c052de3bb16ac53b6b6ed659ec7557eb84c7590 (diff) | |
download | toolchain_gcc-82bcbebce43f0227f506d75a5b764b6847041bae.tar.gz toolchain_gcc-82bcbebce43f0227f506d75a5b764b6847041bae.tar.bz2 toolchain_gcc-82bcbebce43f0227f506d75a5b764b6847041bae.zip |
Initial check-in of gcc 4.7.2.
Change-Id: I4a2f5a921c21741a0e18bda986d77e5f1bef0365
Diffstat (limited to 'gcc-4.7/libgo/runtime/go-matherr.c')
-rw-r--r-- | gcc-4.7/libgo/runtime/go-matherr.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/gcc-4.7/libgo/runtime/go-matherr.c b/gcc-4.7/libgo/runtime/go-matherr.c new file mode 100644 index 000000000..d620ba08b --- /dev/null +++ b/gcc-4.7/libgo/runtime/go-matherr.c @@ -0,0 +1,88 @@ +/* go-matherr.c -- a Go version of the matherr function. + + Copyright 2012 The Go Authors. All rights reserved. + Use of this source code is governed by a BSD-style + license that can be found in the LICENSE file. */ + +/* The gccgo version of the math library calls libc functions. On + some systems, such as Solaris, those functions will call matherr on + exceptional conditions. This is a version of matherr appropriate + for Go, one which returns the values that the Go math library + expects. This is fine for pure Go programs. For mixed Go and C + programs this will be problematic if the C programs themselves use + matherr. Normally the C version of matherr will override this, and + the Go code will just have to cope. If this turns out to be too + problematic we can change to run pure Go code in the math library + on systems that use matherr. */ + +#include <math.h> +#include <stdint.h> + +#include "config.h" + +#if defined(HAVE_MATHERR) && defined(HAVE_STRUCT_EXCEPTION) + +#define PI 3.14159265358979323846264338327950288419716939937510582097494459 + +int +matherr (struct exception* e) +{ + const char *n; + + if (e->type != DOMAIN) + return 0; + + n = e->name; + if (__builtin_strcmp (n, "acos") == 0 + || __builtin_strcmp (n, "asin") == 0) + e->retval = __builtin_nan (""); + else if (__builtin_strcmp (n, "atan2") == 0) + { + if (e->arg1 == 0 && e->arg2 == 0) + { + double nz; + + nz = -0.0; + if (__builtin_memcmp (&e->arg2, &nz, sizeof (double)) != 0) + e->retval = e->arg1; + else + e->retval = copysign (PI, e->arg1); + } + else + return 0; + } + else if (__builtin_strcmp (n, "log") == 0 + || __builtin_strcmp (n, "log10") == 0) + e->retval = __builtin_nan (""); + else if (__builtin_strcmp (n, "pow") == 0) + { + if (e->arg1 < 0) + e->retval = __builtin_nan (""); + else if (e->arg1 == 0 && e->arg2 == 0) + e->retval = 1.0; + else if (e->arg1 == 0 && e->arg2 < 0) + { + double i; + + if (modf (e->arg2, &i) == 0 && ((int64_t) i & 1) == 1) + e->retval = copysign (__builtin_inf (), e->arg1); + else + e->retval = __builtin_inf (); + } + else + return 0; + } + else if (__builtin_strcmp (n, "sqrt") == 0) + { + if (e->arg1 < 0) + e->retval = __builtin_nan (""); + else + return 0; + } + else + return 0; + + return 1; +} + +#endif |