diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2013-10-09 22:31:15 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2013-10-09 22:31:15 +0000 |
commit | 215552adac04bc04778b3052c24d8c66b8455fef (patch) | |
tree | ecca99f169c43eb56f3f628b9248c8e0361b9a0e /gcc/go | |
parent | 4d5b5e9f2c37500cb85e18ce685be3bdd6ba549d (diff) | |
download | gcc-215552adac04bc04778b3052c24d8c66b8455fef.zip gcc-215552adac04bc04778b3052c24d8c66b8455fef.tar.gz gcc-215552adac04bc04778b3052c24d8c66b8455fef.tar.bz2 |
compiler, runtime: Fix complex division of NaN / 0.
From-SVN: r203331
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 37 | ||||
-rw-r--r-- | gcc/go/gofrontend/runtime.cc | 7 | ||||
-rw-r--r-- | gcc/go/gofrontend/runtime.def | 6 |
3 files changed, 50 insertions, 0 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index d5e3a67..9d59349 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -5967,6 +5967,43 @@ Binary_expression::do_get_tree(Translate_context* context) 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); if (compute_type != NULL_TREE) { diff --git a/gcc/go/gofrontend/runtime.cc b/gcc/go/gofrontend/runtime.cc index ecc508d..3b0f1880 100644 --- a/gcc/go/gofrontend/runtime.cc +++ b/gcc/go/gofrontend/runtime.cc @@ -42,6 +42,8 @@ enum Runtime_function_type RFT_RUNE, // Go type float64, C type double. RFT_FLOAT64, + // Go type complex64, C type __complex float. + RFT_COMPLEX64, // Go type complex128, C type __complex double. RFT_COMPLEX128, // 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"); break; + case RFT_COMPLEX64: + t = Type::lookup_complex_type("complex64"); + break; + case RFT_COMPLEX128: t = Type::lookup_complex_type("complex128"); break; @@ -216,6 +222,7 @@ convert_to_runtime_function_type(Runtime_function_type bft, Expression* e, case RFT_UINTPTR: case RFT_RUNE: case RFT_FLOAT64: + case RFT_COMPLEX64: case RFT_COMPLEX128: case RFT_STRING: case RFT_POINTER: diff --git a/gcc/go/gofrontend/runtime.def b/gcc/go/gofrontend/runtime.def index 0d3fd3c..a303a50 100644 --- a/gcc/go/gofrontend/runtime.def +++ b/gcc/go/gofrontend/runtime.def @@ -68,6 +68,12 @@ DEF_GO_RUNTIME(STRING_TO_INT_ARRAY, "__go_string_to_int_array", 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. DEF_GO_RUNTIME(MAKESLICE1, "__go_make_slice1", P2(TYPE, UINTPTR), R1(SLICE)) DEF_GO_RUNTIME(MAKESLICE2, "__go_make_slice2", P3(TYPE, UINTPTR, UINTPTR), |