mirror of git://gcc.gnu.org/git/gcc.git
compiler, runtime: Fix complex division of NaN / 0.
From-SVN: r203331
This commit is contained in:
parent
4d5b5e9f2c
commit
215552adac
|
|
@ -5967,6 +5967,43 @@ Binary_expression::do_get_tree(Translate_context* context)
|
||||||
right);
|
right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For complex division Go wants slightly different results than the
|
||||||
|
// GCC library provides, so we have our own runtime routine.
|
||||||
|
if (this->op_ == OPERATOR_DIV && this->left_->type()->complex_type() != NULL)
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
tree *pdecl;
|
||||||
|
Type* ctype;
|
||||||
|
static tree complex64_div_decl;
|
||||||
|
static tree complex128_div_decl;
|
||||||
|
switch (this->left_->type()->complex_type()->bits())
|
||||||
|
{
|
||||||
|
case 64:
|
||||||
|
name = "__go_complex64_div";
|
||||||
|
pdecl = &complex64_div_decl;
|
||||||
|
ctype = Type::lookup_complex_type("complex64");
|
||||||
|
break;
|
||||||
|
case 128:
|
||||||
|
name = "__go_complex128_div";
|
||||||
|
pdecl = &complex128_div_decl;
|
||||||
|
ctype = Type::lookup_complex_type("complex128");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
go_unreachable();
|
||||||
|
}
|
||||||
|
Btype* cbtype = ctype->get_backend(gogo);
|
||||||
|
tree ctype_tree = type_to_tree(cbtype);
|
||||||
|
return Gogo::call_builtin(pdecl,
|
||||||
|
this->location(),
|
||||||
|
name,
|
||||||
|
2,
|
||||||
|
ctype_tree,
|
||||||
|
ctype_tree,
|
||||||
|
fold_convert_loc(gccloc, ctype_tree, left),
|
||||||
|
type,
|
||||||
|
fold_convert_loc(gccloc, ctype_tree, right));
|
||||||
|
}
|
||||||
|
|
||||||
tree compute_type = excess_precision_type(type);
|
tree compute_type = excess_precision_type(type);
|
||||||
if (compute_type != NULL_TREE)
|
if (compute_type != NULL_TREE)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,8 @@ enum Runtime_function_type
|
||||||
RFT_RUNE,
|
RFT_RUNE,
|
||||||
// Go type float64, C type double.
|
// Go type float64, C type double.
|
||||||
RFT_FLOAT64,
|
RFT_FLOAT64,
|
||||||
|
// Go type complex64, C type __complex float.
|
||||||
|
RFT_COMPLEX64,
|
||||||
// Go type complex128, C type __complex double.
|
// Go type complex128, C type __complex double.
|
||||||
RFT_COMPLEX128,
|
RFT_COMPLEX128,
|
||||||
// Go type string, C type struct __go_string.
|
// Go type string, C type struct __go_string.
|
||||||
|
|
@ -126,6 +128,10 @@ runtime_function_type(Runtime_function_type bft)
|
||||||
t = Type::lookup_float_type("float64");
|
t = Type::lookup_float_type("float64");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case RFT_COMPLEX64:
|
||||||
|
t = Type::lookup_complex_type("complex64");
|
||||||
|
break;
|
||||||
|
|
||||||
case RFT_COMPLEX128:
|
case RFT_COMPLEX128:
|
||||||
t = Type::lookup_complex_type("complex128");
|
t = Type::lookup_complex_type("complex128");
|
||||||
break;
|
break;
|
||||||
|
|
@ -216,6 +222,7 @@ convert_to_runtime_function_type(Runtime_function_type bft, Expression* e,
|
||||||
case RFT_UINTPTR:
|
case RFT_UINTPTR:
|
||||||
case RFT_RUNE:
|
case RFT_RUNE:
|
||||||
case RFT_FLOAT64:
|
case RFT_FLOAT64:
|
||||||
|
case RFT_COMPLEX64:
|
||||||
case RFT_COMPLEX128:
|
case RFT_COMPLEX128:
|
||||||
case RFT_STRING:
|
case RFT_STRING:
|
||||||
case RFT_POINTER:
|
case RFT_POINTER:
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,12 @@ DEF_GO_RUNTIME(STRING_TO_INT_ARRAY, "__go_string_to_int_array",
|
||||||
P1(STRING), R1(SLICE))
|
P1(STRING), R1(SLICE))
|
||||||
|
|
||||||
|
|
||||||
|
// Complex division.
|
||||||
|
DEF_GO_RUNTIME(COMPLEX64_DIV, "__go_complex64_div",
|
||||||
|
P2(COMPLEX64, COMPLEX64), R1(COMPLEX64))
|
||||||
|
DEF_GO_RUNTIME(COMPLEX128_DIV, "__go_complex128_div",
|
||||||
|
P2(COMPLEX128, COMPLEX128), R1(COMPLEX128))
|
||||||
|
|
||||||
// Make a slice.
|
// Make a slice.
|
||||||
DEF_GO_RUNTIME(MAKESLICE1, "__go_make_slice1", P2(TYPE, UINTPTR), R1(SLICE))
|
DEF_GO_RUNTIME(MAKESLICE1, "__go_make_slice1", P2(TYPE, UINTPTR), R1(SLICE))
|
||||||
DEF_GO_RUNTIME(MAKESLICE2, "__go_make_slice2", P3(TYPE, UINTPTR, UINTPTR),
|
DEF_GO_RUNTIME(MAKESLICE2, "__go_make_slice2", P3(TYPE, UINTPTR, UINTPTR),
|
||||||
|
|
|
||||||
|
|
@ -424,6 +424,7 @@ runtime_files = \
|
||||||
runtime/go-caller.c \
|
runtime/go-caller.c \
|
||||||
runtime/go-callers.c \
|
runtime/go-callers.c \
|
||||||
runtime/go-can-convert-interface.c \
|
runtime/go-can-convert-interface.c \
|
||||||
|
runtime/go-cdiv.c \
|
||||||
runtime/go-cgo.c \
|
runtime/go-cgo.c \
|
||||||
runtime/go-check-interface.c \
|
runtime/go-check-interface.c \
|
||||||
runtime/go-construct-map.c \
|
runtime/go-construct-map.c \
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,7 @@ libgo_la_DEPENDENCIES = $(am__DEPENDENCIES_2) \
|
||||||
@LIBGO_IS_LINUX_TRUE@am__objects_5 = getncpu-linux.lo
|
@LIBGO_IS_LINUX_TRUE@am__objects_5 = getncpu-linux.lo
|
||||||
am__objects_6 = go-append.lo go-assert.lo go-assert-interface.lo \
|
am__objects_6 = go-append.lo go-assert.lo go-assert-interface.lo \
|
||||||
go-byte-array-to-string.lo go-breakpoint.lo go-caller.lo \
|
go-byte-array-to-string.lo go-breakpoint.lo go-caller.lo \
|
||||||
go-callers.lo go-can-convert-interface.lo go-cgo.lo \
|
go-callers.lo go-can-convert-interface.lo go-cdiv.lo go-cgo.lo \
|
||||||
go-check-interface.lo go-construct-map.lo \
|
go-check-interface.lo go-construct-map.lo \
|
||||||
go-convert-interface.lo go-copy.lo go-defer.lo \
|
go-convert-interface.lo go-copy.lo go-defer.lo \
|
||||||
go-deferred-recover.lo go-eface-compare.lo \
|
go-deferred-recover.lo go-eface-compare.lo \
|
||||||
|
|
@ -757,6 +757,7 @@ runtime_files = \
|
||||||
runtime/go-caller.c \
|
runtime/go-caller.c \
|
||||||
runtime/go-callers.c \
|
runtime/go-callers.c \
|
||||||
runtime/go-can-convert-interface.c \
|
runtime/go-can-convert-interface.c \
|
||||||
|
runtime/go-cdiv.c \
|
||||||
runtime/go-cgo.c \
|
runtime/go-cgo.c \
|
||||||
runtime/go-check-interface.c \
|
runtime/go-check-interface.c \
|
||||||
runtime/go-construct-map.c \
|
runtime/go-construct-map.c \
|
||||||
|
|
@ -2368,6 +2369,7 @@ distclean-compile:
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-caller.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-caller.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-callers.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-callers.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-can-convert-interface.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-can-convert-interface.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-cdiv.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-cgo.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-cgo.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-check-interface.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-check-interface.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-construct-map.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-construct-map.Plo@am__quote@
|
||||||
|
|
@ -2554,6 +2556,13 @@ go-can-convert-interface.lo: runtime/go-can-convert-interface.c
|
||||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-can-convert-interface.lo `test -f 'runtime/go-can-convert-interface.c' || echo '$(srcdir)/'`runtime/go-can-convert-interface.c
|
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-can-convert-interface.lo `test -f 'runtime/go-can-convert-interface.c' || echo '$(srcdir)/'`runtime/go-can-convert-interface.c
|
||||||
|
|
||||||
|
go-cdiv.lo: runtime/go-cdiv.c
|
||||||
|
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-cdiv.lo -MD -MP -MF $(DEPDIR)/go-cdiv.Tpo -c -o go-cdiv.lo `test -f 'runtime/go-cdiv.c' || echo '$(srcdir)/'`runtime/go-cdiv.c
|
||||||
|
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-cdiv.Tpo $(DEPDIR)/go-cdiv.Plo
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-cdiv.c' object='go-cdiv.lo' libtool=yes @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-cdiv.lo `test -f 'runtime/go-cdiv.c' || echo '$(srcdir)/'`runtime/go-cdiv.c
|
||||||
|
|
||||||
go-cgo.lo: runtime/go-cgo.c
|
go-cgo.lo: runtime/go-cgo.c
|
||||||
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-cgo.lo -MD -MP -MF $(DEPDIR)/go-cgo.Tpo -c -o go-cgo.lo `test -f 'runtime/go-cgo.c' || echo '$(srcdir)/'`runtime/go-cgo.c
|
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-cgo.lo -MD -MP -MF $(DEPDIR)/go-cgo.Tpo -c -o go-cgo.lo `test -f 'runtime/go-cgo.c' || echo '$(srcdir)/'`runtime/go-cgo.c
|
||||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-cgo.Tpo $(DEPDIR)/go-cgo.Plo
|
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-cgo.Tpo $(DEPDIR)/go-cgo.Plo
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
/* go-cdiv.c -- complex division routines
|
||||||
|
|
||||||
|
Copyright 2013 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. */
|
||||||
|
|
||||||
|
/* Calls to these functions are generated by the Go frontend for
|
||||||
|
division of complex64 or complex128. We use these because Go's
|
||||||
|
complex division expects slightly different results from the GCC
|
||||||
|
default. When dividing NaN+1.0i / 0+0i, Go expects NaN+NaNi but
|
||||||
|
GCC generates NaN+Infi. NaN+Infi seems wrong seems the rules of
|
||||||
|
C99 Annex G specify that if either side of a complex number is Inf,
|
||||||
|
the the whole number is Inf, but an operation involving NaN ought
|
||||||
|
to result in NaN, not Inf. */
|
||||||
|
|
||||||
|
__complex float
|
||||||
|
__go_complex64_div (__complex float a, __complex float b)
|
||||||
|
{
|
||||||
|
if (__builtin_expect (b == 0+0i, 0))
|
||||||
|
{
|
||||||
|
if (!__builtin_isinff (__real__ a)
|
||||||
|
&& !__builtin_isinff (__imag__ a)
|
||||||
|
&& (__builtin_isnanf (__real__ a) || __builtin_isnanf (__imag__ a)))
|
||||||
|
{
|
||||||
|
/* Pass "1" to nanf to match math/bits.go. */
|
||||||
|
return __builtin_nanf("1") + __builtin_nanf("1")*1i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return a / b;
|
||||||
|
}
|
||||||
|
|
||||||
|
__complex double
|
||||||
|
__go_complex128_div (__complex double a, __complex double b)
|
||||||
|
{
|
||||||
|
if (__builtin_expect (b == 0+0i, 0))
|
||||||
|
{
|
||||||
|
if (!__builtin_isinf (__real__ a)
|
||||||
|
&& !__builtin_isinf (__imag__ a)
|
||||||
|
&& (__builtin_isnan (__real__ a) || __builtin_isnan (__imag__ a)))
|
||||||
|
{
|
||||||
|
/* Pass "1" to nan to match math/bits.go. */
|
||||||
|
return __builtin_nan("1") + __builtin_nan("1")*1i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return a / b;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue