aboutsummaryrefslogtreecommitdiff
path: root/gcc/go/gofrontend/expressions.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2013-10-09 22:31:15 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2013-10-09 22:31:15 +0000
commit215552adac04bc04778b3052c24d8c66b8455fef (patch)
treeecca99f169c43eb56f3f628b9248c8e0361b9a0e /gcc/go/gofrontend/expressions.cc
parent4d5b5e9f2c37500cb85e18ce685be3bdd6ba549d (diff)
downloadgcc-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/gofrontend/expressions.cc')
-rw-r--r--gcc/go/gofrontend/expressions.cc37
1 files changed, 37 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)
{