aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-09-09 13:45:33 +0000
committerGitHub <noreply@github.com>2021-09-09 13:45:33 +0000
commit55f60bd6fe2db6831762e243577515824e2fca5c (patch)
treeb7fa367ee6c97ae3a5b9ab69bb7b1be0e02418c4
parent38f2795947ab8d8080bab81c5e2ccdd24981cbcc (diff)
parent4faa7d7765f5840779c542430ca6aa9118008a5b (diff)
downloadgcc-55f60bd6fe2db6831762e243577515824e2fca5c.zip
gcc-55f60bd6fe2db6831762e243577515824e2fca5c.tar.gz
gcc-55f60bd6fe2db6831762e243577515824e2fca5c.tar.bz2
Merge #659
659: Initial intrinsics builtin block r=philberty a=philberty This is the initial piece to get the simple intrinsic's mapped over to GCC ones. The GCC wrapper contains a mapping system of rust names over to the builtin gcc names as far as I can tell gcc will allow for fallback onto linking against -lm. I think this will be a nice piece of work for new contributors, given the number of intrinsics Addresses #658 Co-authored-by: Philip Herron <philip.herron@embecosm.com> Co-authored-by: Thomas Schwinge <thomas@codesourcery.com>
-rw-r--r--gcc/rust/Make-lang.in1
-rw-r--r--gcc/rust/backend/rust-compile-base.h2
-rw-r--r--gcc/rust/backend/rust-compile-extern.h10
-rw-r--r--gcc/rust/backend/rust-compile-intrinsic.cc91
-rw-r--r--gcc/rust/backend/rust-compile-intrinsic.h39
-rw-r--r--gcc/rust/rust-backend.h4
-rw-r--r--gcc/rust/rust-gcc.cc508
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-implitem.h34
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-stmt.h11
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-toplevel.h13
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc11
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc2
-rw-r--r--gcc/rust/typecheck/rust-tyty.h50
-rw-r--r--gcc/testsuite/rust/compile/torture/intrinsics-1.rs16
14 files changed, 473 insertions, 319 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 14294f3..0e181a6 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -87,6 +87,7 @@ GRS_OBJS = \
rust/rust-hir-type-check-type.o \
rust/rust-lint-marklive.o \
rust/rust-hir-type-check-path.o \
+ rust/rust-compile-intrinsic.o \
$(END)
# removed object files from here
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
index c0cfacf..5a26862 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -1,5 +1,3 @@
-
-
// This file is part of GCC.
// GCC is free software; you can redistribute it and/or modify it under
diff --git a/gcc/rust/backend/rust-compile-extern.h b/gcc/rust/backend/rust-compile-extern.h
index a0ad200..d78a566 100644
--- a/gcc/rust/backend/rust-compile-extern.h
+++ b/gcc/rust/backend/rust-compile-extern.h
@@ -20,6 +20,7 @@
#define RUST_COMPILE_EXTERN_ITEM
#include "rust-compile-base.h"
+#include "rust-compile-intrinsic.h"
#include "rust-compile-tyty.h"
#include "rust-compile-implitem.h"
#include "rust-compile-var-decl.h"
@@ -118,6 +119,15 @@ public:
fntype->override_context ();
}
+ if (fntype->get_abi () == TyTy::FnType::ABI::INTRINSIC)
+ {
+ Intrinsics compile (ctx);
+ Bfunction *fndecl = compile.compile (fntype);
+ ctx->insert_function_decl (fntype->get_ty_ref (), fndecl, fntype);
+ return;
+ }
+
+ rust_assert (fntype->get_abi () == TyTy::FnType::ABI::C);
::Btype *compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
const unsigned int flags
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc
new file mode 100644
index 0000000..4068a7a
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -0,0 +1,91 @@
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC 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 General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-compile-intrinsic.h"
+
+namespace Rust {
+namespace Compile {
+
+Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {}
+
+Bfunction *
+Intrinsics::compile (TyTy::FnType *fntype)
+{
+ rust_assert (fntype->get_abi () == TyTy::FnType::ABI::INTRINSIC);
+
+ // https://github.com/rust-lang/rust/blob/master/compiler/rustc_codegen_llvm/src/intrinsic.rs
+ // https://github.com/Rust-GCC/gccrs/issues/658
+
+ // let llvm_name = match name {
+ // sym::sqrtf32 => "llvm.sqrt.f32",
+ // sym::sqrtf64 => "llvm.sqrt.f64",
+ // sym::powif32 => "llvm.powi.f32",
+ // sym::powif64 => "llvm.powi.f64",
+ // sym::sinf32 => "llvm.sin.f32",
+ // sym::sinf64 => "llvm.sin.f64",
+ // sym::cosf32 => "llvm.cos.f32",
+ // sym::cosf64 => "llvm.cos.f64",
+ // sym::powf32 => "llvm.pow.f32",
+ // sym::powf64 => "llvm.pow.f64",
+ // sym::expf32 => "llvm.exp.f32",
+ // sym::expf64 => "llvm.exp.f64",
+ // sym::exp2f32 => "llvm.exp2.f32",
+ // sym::exp2f64 => "llvm.exp2.f64",
+ // sym::logf32 => "llvm.log.f32",
+ // sym::logf64 => "llvm.log.f64",
+ // sym::log10f32 => "llvm.log10.f32",
+ // sym::log10f64 => "llvm.log10.f64",
+ // sym::log2f32 => "llvm.log2.f32",
+ // sym::log2f64 => "llvm.log2.f64",
+ // sym::fmaf32 => "llvm.fma.f32",
+ // sym::fmaf64 => "llvm.fma.f64",
+ // sym::fabsf32 => "llvm.fabs.f32",
+ // sym::fabsf64 => "llvm.fabs.f64",
+ // sym::minnumf32 => "llvm.minnum.f32",
+ // sym::minnumf64 => "llvm.minnum.f64",
+ // sym::maxnumf32 => "llvm.maxnum.f32",
+ // sym::maxnumf64 => "llvm.maxnum.f64",
+ // sym::copysignf32 => "llvm.copysign.f32",
+ // sym::copysignf64 => "llvm.copysign.f64",
+ // sym::floorf32 => "llvm.floor.f32",
+ // sym::floorf64 => "llvm.floor.f64",
+ // sym::ceilf32 => "llvm.ceil.f32",
+ // sym::ceilf64 => "llvm.ceil.f64",
+ // sym::truncf32 => "llvm.trunc.f32",
+ // sym::truncf64 => "llvm.trunc.f64",
+ // sym::rintf32 => "llvm.rint.f32",
+ // sym::rintf64 => "llvm.rint.f64",
+ // sym::nearbyintf32 => "llvm.nearbyint.f32",
+ // sym::nearbyintf64 => "llvm.nearbyint.f64",
+ // sym::roundf32 => "llvm.round.f32",
+ // sym::roundf64 => "llvm.round.f64",
+ // _ => return None,
+ // };
+ // Some(cx.get_intrinsic(&llvm_name))
+
+ Bfunction *builtin = ctx->get_backend ()->lookup_builtin_by_rust_name (
+ fntype->get_identifier ());
+ if (builtin != nullptr)
+ return builtin;
+
+ Location locus = ctx->get_mappings ()->lookup_location (fntype->get_ref ());
+ rust_error_at (locus, "unknown builtin");
+
+ return ctx->get_backend ()->error_function ();
+}
+
+} // namespace Compile
+} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-intrinsic.h b/gcc/rust/backend/rust-compile-intrinsic.h
new file mode 100644
index 0000000..25e298a
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-intrinsic.h
@@ -0,0 +1,39 @@
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC 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 General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_COMPILE_INTRINSIC
+#define RUST_COMPILE_INTRINSIC
+
+#include "rust-compile-context.h"
+
+namespace Rust {
+namespace Compile {
+
+class Intrinsics
+{
+public:
+ Intrinsics (Context *ctx);
+
+ Bfunction *compile (TyTy::FnType *fntype);
+
+private:
+ Context *ctx;
+};
+
+} // namespace Compile
+} // namespace Rust
+
+#endif // RUST_COMPILE_INTRINSIC
diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h
index 1af76cf..105b2ea 100644
--- a/gcc/rust/rust-backend.h
+++ b/gcc/rust/rust-backend.h
@@ -842,7 +842,9 @@ public:
// Look up a named built-in function in the current backend implementation.
// Returns NULL if no built-in function by that name exists.
- virtual Bfunction *lookup_builtin (const std::string &) = 0;
+ virtual Bfunction *lookup_gcc_builtin (const std::string &) = 0;
+
+ virtual Bfunction *lookup_builtin_by_rust_name (const std::string &) = 0;
// Utility.
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 1edb7f1..4c1dda8 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -512,7 +512,9 @@ public:
bool function_set_body (Bfunction *function, Bstatement *code_stmt);
- Bfunction *lookup_builtin (const std::string &);
+ Bfunction *lookup_gcc_builtin (const std::string &);
+
+ Bfunction *lookup_builtin_by_rust_name (const std::string &);
void write_global_definitions (const std::vector<Btype *> &,
const std::vector<Bexpression *> &,
@@ -546,11 +548,13 @@ private:
static const int builtin_noreturn = 1 << 1;
static const int builtin_novops = 1 << 2;
- void define_builtin (built_in_function bcode, const char *name,
- const char *libname, tree fntype, int flags);
+ void define_builtin (const std::string rust_name, built_in_function bcode,
+ const char *name, const char *libname, tree fntype,
+ int flags);
// A mapping of the GCC built-ins exposed to GCCRust.
std::map<std::string, Bfunction *> builtin_functions_;
+ std::map<std::string, std::string> rust_intrinsic_to_gcc_builtin;
};
// A helper function to create a GCC identifier from a C++ string.
@@ -567,303 +571,230 @@ Gcc_backend::Gcc_backend ()
{
/* We need to define the fetch_and_add functions, since we use them
for ++ and --. */
- tree t = this->integer_type (true, BITS_PER_UNIT)->get_tree ();
- tree p = build_pointer_type (build_qualified_type (t, TYPE_QUAL_VOLATILE));
- this->define_builtin (BUILT_IN_SYNC_ADD_AND_FETCH_1, "__sync_fetch_and_add_1",
- NULL, build_function_type_list (t, p, t, NULL_TREE), 0);
-
- t = this->integer_type (true, BITS_PER_UNIT * 2)->get_tree ();
- p = build_pointer_type (build_qualified_type (t, TYPE_QUAL_VOLATILE));
- this->define_builtin (BUILT_IN_SYNC_ADD_AND_FETCH_2, "__sync_fetch_and_add_2",
- NULL, build_function_type_list (t, p, t, NULL_TREE), 0);
-
- t = this->integer_type (true, BITS_PER_UNIT * 4)->get_tree ();
- p = build_pointer_type (build_qualified_type (t, TYPE_QUAL_VOLATILE));
- this->define_builtin (BUILT_IN_SYNC_ADD_AND_FETCH_4, "__sync_fetch_and_add_4",
- NULL, build_function_type_list (t, p, t, NULL_TREE), 0);
-
- t = this->integer_type (true, BITS_PER_UNIT * 8)->get_tree ();
- p = build_pointer_type (build_qualified_type (t, TYPE_QUAL_VOLATILE));
- this->define_builtin (BUILT_IN_SYNC_ADD_AND_FETCH_8, "__sync_fetch_and_add_8",
- NULL, build_function_type_list (t, p, t, NULL_TREE), 0);
-
- // We use __builtin_expect for magic import functions.
- this->define_builtin (BUILT_IN_EXPECT, "__builtin_expect", NULL,
- build_function_type_list (long_integer_type_node,
- long_integer_type_node,
- long_integer_type_node,
- NULL_TREE),
- builtin_const);
-
- // We use __builtin_memcmp for struct comparisons.
- this->define_builtin (BUILT_IN_MEMCMP, "__builtin_memcmp", "memcmp",
- build_function_type_list (integer_type_node,
- const_ptr_type_node,
- const_ptr_type_node,
- size_type_node, NULL_TREE),
- 0);
-
- // We use __builtin_memmove for copying data.
- this->define_builtin (BUILT_IN_MEMMOVE, "__builtin_memmove", "memmove",
- build_function_type_list (void_type_node, ptr_type_node,
- const_ptr_type_node,
- size_type_node, NULL_TREE),
- 0);
-
- // We use __builtin_memset for zeroing data.
- this->define_builtin (BUILT_IN_MEMSET, "__builtin_memset", "memset",
- build_function_type_list (void_type_node, ptr_type_node,
- integer_type_node,
- size_type_node, NULL_TREE),
- 0);
-
- // Used by runtime/internal/sys and math/bits.
- this->define_builtin (BUILT_IN_CTZ, "__builtin_ctz", "ctz",
- build_function_type_list (integer_type_node,
- unsigned_type_node,
- NULL_TREE),
- builtin_const);
- this->define_builtin (BUILT_IN_CTZLL, "__builtin_ctzll", "ctzll",
- build_function_type_list (integer_type_node,
- long_long_unsigned_type_node,
- NULL_TREE),
- builtin_const);
- this->define_builtin (BUILT_IN_CLZ, "__builtin_clz", "clz",
- build_function_type_list (integer_type_node,
- unsigned_type_node,
- NULL_TREE),
- builtin_const);
- this->define_builtin (BUILT_IN_CLZLL, "__builtin_clzll", "clzll",
- build_function_type_list (integer_type_node,
- long_long_unsigned_type_node,
- NULL_TREE),
- builtin_const);
- this->define_builtin (BUILT_IN_POPCOUNT, "__builtin_popcount", "popcount",
- build_function_type_list (integer_type_node,
- unsigned_type_node,
- NULL_TREE),
- builtin_const);
- this->define_builtin (BUILT_IN_POPCOUNTLL, "__builtin_popcountll",
- "popcountll",
- build_function_type_list (integer_type_node,
- long_long_unsigned_type_node,
- NULL_TREE),
- builtin_const);
- this->define_builtin (BUILT_IN_BSWAP16, "__builtin_bswap16", "bswap16",
- build_function_type_list (uint16_type_node,
- uint16_type_node, NULL_TREE),
- builtin_const);
- this->define_builtin (BUILT_IN_BSWAP32, "__builtin_bswap32", "bswap32",
- build_function_type_list (uint32_type_node,
- uint32_type_node, NULL_TREE),
- builtin_const);
- this->define_builtin (BUILT_IN_BSWAP64, "__builtin_bswap64", "bswap64",
- build_function_type_list (uint64_type_node,
- uint64_type_node, NULL_TREE),
- builtin_const);
+ // tree t = this->integer_type (true, BITS_PER_UNIT)->get_tree ();
+ // tree p = build_pointer_type (build_qualified_type (t, TYPE_QUAL_VOLATILE));
+ // this->define_builtin (BUILT_IN_SYNC_ADD_AND_FETCH_1,
+ // "__sync_fetch_and_add_1",
+ // NULL, build_function_type_list (t, p, t, NULL_TREE), 0);
+
+ // t = this->integer_type (true, BITS_PER_UNIT * 2)->get_tree ();
+ // p = build_pointer_type (build_qualified_type (t, TYPE_QUAL_VOLATILE));
+ // this->define_builtin (BUILT_IN_SYNC_ADD_AND_FETCH_2,
+ // "__sync_fetch_and_add_2",
+ // NULL, build_function_type_list (t, p, t, NULL_TREE), 0);
+
+ // t = this->integer_type (true, BITS_PER_UNIT * 4)->get_tree ();
+ // p = build_pointer_type (build_qualified_type (t, TYPE_QUAL_VOLATILE));
+ // this->define_builtin (BUILT_IN_SYNC_ADD_AND_FETCH_4,
+ // "__sync_fetch_and_add_4",
+ // NULL, build_function_type_list (t, p, t, NULL_TREE), 0);
+
+ // t = this->integer_type (true, BITS_PER_UNIT * 8)->get_tree ();
+ // p = build_pointer_type (build_qualified_type (t, TYPE_QUAL_VOLATILE));
+ // this->define_builtin (BUILT_IN_SYNC_ADD_AND_FETCH_8,
+ // "__sync_fetch_and_add_8",
+ // NULL, build_function_type_list (t, p, t, NULL_TREE), 0);
+
+ // // We use __builtin_expect for magic import functions.
+ // this->define_builtin (BUILT_IN_EXPECT, "__builtin_expect", NULL,
+ // build_function_type_list (long_integer_type_node,
+ // long_integer_type_node,
+ // long_integer_type_node,
+ // NULL_TREE),
+ // builtin_const);
+
+ // // We use __builtin_memcmp for struct comparisons.
+ // this->define_builtin (BUILT_IN_MEMCMP, "__builtin_memcmp", "memcmp",
+ // build_function_type_list (integer_type_node,
+ // const_ptr_type_node,
+ // const_ptr_type_node,
+ // size_type_node, NULL_TREE),
+ // 0);
+
+ // // We use __builtin_memmove for copying data.
+ // this->define_builtin (BUILT_IN_MEMMOVE, "__builtin_memmove", "memmove",
+ // build_function_type_list (void_type_node, ptr_type_node,
+ // const_ptr_type_node,
+ // size_type_node, NULL_TREE),
+ // 0);
+
+ // // We use __builtin_memset for zeroing data.
+ // this->define_builtin (BUILT_IN_MEMSET, "__builtin_memset", "memset",
+ // build_function_type_list (void_type_node, ptr_type_node,
+ // integer_type_node,
+ // size_type_node, NULL_TREE),
+ // 0);
+
+ // // Used by runtime/internal/sys and math/bits.
+ // this->define_builtin (BUILT_IN_CTZ, "__builtin_ctz", "ctz",
+ // build_function_type_list (integer_type_node,
+ // unsigned_type_node,
+ // NULL_TREE),
+ // builtin_const);
+ // this->define_builtin (BUILT_IN_CTZLL, "__builtin_ctzll", "ctzll",
+ // build_function_type_list (integer_type_node,
+ // long_long_unsigned_type_node,
+ // NULL_TREE),
+ // builtin_const);
+ // this->define_builtin (BUILT_IN_CLZ, "__builtin_clz", "clz",
+ // build_function_type_list (integer_type_node,
+ // unsigned_type_node,
+ // NULL_TREE),
+ // builtin_const);
+ // this->define_builtin (BUILT_IN_CLZLL, "__builtin_clzll", "clzll",
+ // build_function_type_list (integer_type_node,
+ // long_long_unsigned_type_node,
+ // NULL_TREE),
+ // builtin_const);
+ // this->define_builtin (BUILT_IN_POPCOUNT, "__builtin_popcount", "popcount",
+ // build_function_type_list (integer_type_node,
+ // unsigned_type_node,
+ // NULL_TREE),
+ // builtin_const);
+ // this->define_builtin (BUILT_IN_POPCOUNTLL, "__builtin_popcountll",
+ // "popcountll",
+ // build_function_type_list (integer_type_node,
+ // long_long_unsigned_type_node,
+ // NULL_TREE),
+ // builtin_const);
+ // this->define_builtin (BUILT_IN_BSWAP16, "__builtin_bswap16", "bswap16",
+ // build_function_type_list (uint16_type_node,
+ // uint16_type_node, NULL_TREE),
+ // builtin_const);
+ // this->define_builtin (BUILT_IN_BSWAP32, "__builtin_bswap32", "bswap32",
+ // build_function_type_list (uint32_type_node,
+ // uint32_type_node, NULL_TREE),
+ // builtin_const);
+ // this->define_builtin (BUILT_IN_BSWAP64, "__builtin_bswap64", "bswap64",
+ // build_function_type_list (uint64_type_node,
+ // uint64_type_node, NULL_TREE),
+ // builtin_const);
// We provide some functions for the math library.
- tree math_function_type
- = build_function_type_list (double_type_node, double_type_node, NULL_TREE);
- tree math_function_type_long
- = build_function_type_list (long_double_type_node, long_double_type_node,
- NULL_TREE);
- tree math_function_type_two
- = build_function_type_list (double_type_node, double_type_node,
- double_type_node, NULL_TREE);
- tree math_function_type_long_two
- = build_function_type_list (long_double_type_node, long_double_type_node,
- long_double_type_node, NULL_TREE);
- this->define_builtin (BUILT_IN_ACOS, "__builtin_acos", "acos",
- math_function_type, builtin_const);
- this->define_builtin (BUILT_IN_ACOSL, "__builtin_acosl", "acosl",
- math_function_type_long, builtin_const);
- this->define_builtin (BUILT_IN_ASIN, "__builtin_asin", "asin",
- math_function_type, builtin_const);
- this->define_builtin (BUILT_IN_ASINL, "__builtin_asinl", "asinl",
- math_function_type_long, builtin_const);
- this->define_builtin (BUILT_IN_ATAN, "__builtin_atan", "atan",
- math_function_type, builtin_const);
- this->define_builtin (BUILT_IN_ATANL, "__builtin_atanl", "atanl",
- math_function_type_long, builtin_const);
- this->define_builtin (BUILT_IN_ATAN2, "__builtin_atan2", "atan2",
- math_function_type_two, builtin_const);
- this->define_builtin (BUILT_IN_ATAN2L, "__builtin_atan2l", "atan2l",
- math_function_type_long_two, builtin_const);
- this->define_builtin (BUILT_IN_CEIL, "__builtin_ceil", "ceil",
- math_function_type, builtin_const);
- this->define_builtin (BUILT_IN_CEILL, "__builtin_ceill", "ceill",
- math_function_type_long, builtin_const);
- this->define_builtin (BUILT_IN_COS, "__builtin_cos", "cos",
- math_function_type, builtin_const);
- this->define_builtin (BUILT_IN_COSL, "__builtin_cosl", "cosl",
- math_function_type_long, builtin_const);
- this->define_builtin (BUILT_IN_EXP, "__builtin_exp", "exp",
- math_function_type, builtin_const);
- this->define_builtin (BUILT_IN_EXPL, "__builtin_expl", "expl",
- math_function_type_long, builtin_const);
- this->define_builtin (BUILT_IN_EXPM1, "__builtin_expm1", "expm1",
- math_function_type, builtin_const);
- this->define_builtin (BUILT_IN_EXPM1L, "__builtin_expm1l", "expm1l",
- math_function_type_long, builtin_const);
- this->define_builtin (BUILT_IN_FABS, "__builtin_fabs", "fabs",
- math_function_type, builtin_const);
- this->define_builtin (BUILT_IN_FABSL, "__builtin_fabsl", "fabsl",
- math_function_type_long, builtin_const);
- this->define_builtin (BUILT_IN_FLOOR, "__builtin_floor", "floor",
- math_function_type, builtin_const);
- this->define_builtin (BUILT_IN_FLOORL, "__builtin_floorl", "floorl",
- math_function_type_long, builtin_const);
- this->define_builtin (BUILT_IN_FMOD, "__builtin_fmod", "fmod",
- math_function_type_two, builtin_const);
- this->define_builtin (BUILT_IN_FMODL, "__builtin_fmodl", "fmodl",
- math_function_type_long_two, builtin_const);
- this->define_builtin (BUILT_IN_LDEXP, "__builtin_ldexp", "ldexp",
- build_function_type_list (double_type_node,
- double_type_node,
- integer_type_node, NULL_TREE),
- builtin_const);
- this->define_builtin (BUILT_IN_LDEXPL, "__builtin_ldexpl", "ldexpl",
- build_function_type_list (long_double_type_node,
- long_double_type_node,
- integer_type_node, NULL_TREE),
- builtin_const);
- this->define_builtin (BUILT_IN_LOG, "__builtin_log", "log",
- math_function_type, builtin_const);
- this->define_builtin (BUILT_IN_LOGL, "__builtin_logl", "logl",
- math_function_type_long, builtin_const);
- this->define_builtin (BUILT_IN_LOG1P, "__builtin_log1p", "log1p",
- math_function_type, builtin_const);
- this->define_builtin (BUILT_IN_LOG1PL, "__builtin_log1pl", "log1pl",
- math_function_type_long, builtin_const);
- this->define_builtin (BUILT_IN_LOG10, "__builtin_log10", "log10",
- math_function_type, builtin_const);
- this->define_builtin (BUILT_IN_LOG10L, "__builtin_log10l", "log10l",
- math_function_type_long, builtin_const);
- this->define_builtin (BUILT_IN_LOG2, "__builtin_log2", "log2",
- math_function_type, builtin_const);
- this->define_builtin (BUILT_IN_LOG2L, "__builtin_log2l", "log2l",
- math_function_type_long, builtin_const);
- this->define_builtin (BUILT_IN_SIN, "__builtin_sin", "sin",
- math_function_type, builtin_const);
- this->define_builtin (BUILT_IN_SINL, "__builtin_sinl", "sinl",
- math_function_type_long, builtin_const);
- this->define_builtin (BUILT_IN_SQRT, "__builtin_sqrt", "sqrt",
- math_function_type, builtin_const);
- this->define_builtin (BUILT_IN_SQRTL, "__builtin_sqrtl", "sqrtl",
- math_function_type_long, builtin_const);
- this->define_builtin (BUILT_IN_TAN, "__builtin_tan", "tan",
- math_function_type, builtin_const);
- this->define_builtin (BUILT_IN_TANL, "__builtin_tanl", "tanl",
- math_function_type_long, builtin_const);
- this->define_builtin (BUILT_IN_TRUNC, "__builtin_trunc", "trunc",
- math_function_type, builtin_const);
- this->define_builtin (BUILT_IN_TRUNCL, "__builtin_truncl", "truncl",
- math_function_type_long, builtin_const);
+ tree math_function_type_f32
+ = build_function_type_list (float_type_node, float_type_node, NULL_TREE);
+
+ this->define_builtin ("sinf32", BUILT_IN_SINF, "__builtin_sinf", "sinf",
+ math_function_type_f32, builtin_const);
+
+ this->define_builtin ("sqrtf32", BUILT_IN_SQRTF, "__builtin_sqrtf", "sqrtf",
+ math_function_type_f32, builtin_const);
// We use __builtin_return_address in the thunk we build for
// functions which call recover, and for runtime.getcallerpc.
- t = build_function_type_list (ptr_type_node, unsigned_type_node, NULL_TREE);
- this->define_builtin (BUILT_IN_RETURN_ADDRESS, "__builtin_return_address",
- NULL, t, 0);
+ // t = build_function_type_list (ptr_type_node, unsigned_type_node,
+ // NULL_TREE); this->define_builtin (BUILT_IN_RETURN_ADDRESS,
+ // "__builtin_return_address",
+ // NULL, t, 0);
// The runtime calls __builtin_dwarf_cfa for runtime.getcallersp.
- t = build_function_type_list (ptr_type_node, NULL_TREE);
- this->define_builtin (BUILT_IN_DWARF_CFA, "__builtin_dwarf_cfa", NULL, t, 0);
+ // t = build_function_type_list (ptr_type_node, NULL_TREE);
+ // this->define_builtin (BUILT_IN_DWARF_CFA, "__builtin_dwarf_cfa", NULL, t,
+ // 0);
// The runtime calls __builtin_extract_return_addr when recording
// the address to which a function returns.
- this->define_builtin (
- BUILT_IN_EXTRACT_RETURN_ADDR, "__builtin_extract_return_addr", NULL,
- build_function_type_list (ptr_type_node, ptr_type_node, NULL_TREE), 0);
+ // this->define_builtin (
+ // BUILT_IN_EXTRACT_RETURN_ADDR, "__builtin_extract_return_addr", NULL,
+ // build_function_type_list (ptr_type_node, ptr_type_node, NULL_TREE), 0);
// The compiler uses __builtin_trap for some exception handling
// cases.
- this->define_builtin (BUILT_IN_TRAP, "__builtin_trap", NULL,
- build_function_type (void_type_node, void_list_node),
- builtin_noreturn);
+ // this->define_builtin (BUILT_IN_TRAP, "__builtin_trap", NULL,
+ // build_function_type (void_type_node, void_list_node),
+ // builtin_noreturn);
// The runtime uses __builtin_prefetch.
- this->define_builtin (BUILT_IN_PREFETCH, "__builtin_prefetch", NULL,
- build_varargs_function_type_list (void_type_node,
- const_ptr_type_node,
- NULL_TREE),
- builtin_novops);
+ // this->define_builtin (BUILT_IN_PREFETCH, "__builtin_prefetch", NULL,
+ // build_varargs_function_type_list (void_type_node,
+ // const_ptr_type_node,
+ // NULL_TREE),
+ // builtin_novops);
// The compiler uses __builtin_unreachable for cases that cannot
// occur.
- this->define_builtin (BUILT_IN_UNREACHABLE, "__builtin_unreachable", NULL,
- build_function_type (void_type_node, void_list_node),
- builtin_const | builtin_noreturn);
+ // this->define_builtin (BUILT_IN_UNREACHABLE, "__builtin_unreachable", NULL,
+ // build_function_type (void_type_node, void_list_node),
+ // builtin_const | builtin_noreturn);
// We provide some atomic functions.
- t = build_function_type_list (uint32_type_node, ptr_type_node,
- integer_type_node, NULL_TREE);
- this->define_builtin (BUILT_IN_ATOMIC_LOAD_4, "__atomic_load_4", NULL, t, 0);
-
- t = build_function_type_list (uint64_type_node, ptr_type_node,
- integer_type_node, NULL_TREE);
- this->define_builtin (BUILT_IN_ATOMIC_LOAD_8, "__atomic_load_8", NULL, t, 0);
-
- t = build_function_type_list (void_type_node, ptr_type_node, uint32_type_node,
- integer_type_node, NULL_TREE);
- this->define_builtin (BUILT_IN_ATOMIC_STORE_4, "__atomic_store_4", NULL, t,
- 0);
-
- t = build_function_type_list (void_type_node, ptr_type_node, uint64_type_node,
- integer_type_node, NULL_TREE);
- this->define_builtin (BUILT_IN_ATOMIC_STORE_8, "__atomic_store_8", NULL, t,
- 0);
-
- t = build_function_type_list (uint32_type_node, ptr_type_node,
- uint32_type_node, integer_type_node, NULL_TREE);
- this->define_builtin (BUILT_IN_ATOMIC_EXCHANGE_4, "__atomic_exchange_4", NULL,
- t, 0);
-
- t = build_function_type_list (uint64_type_node, ptr_type_node,
- uint64_type_node, integer_type_node, NULL_TREE);
- this->define_builtin (BUILT_IN_ATOMIC_EXCHANGE_8, "__atomic_exchange_8", NULL,
- t, 0);
-
- t = build_function_type_list (boolean_type_node, ptr_type_node, ptr_type_node,
- uint32_type_node, boolean_type_node,
- integer_type_node, integer_type_node,
- NULL_TREE);
- this->define_builtin (BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4,
- "__atomic_compare_exchange_4", NULL, t, 0);
-
- t = build_function_type_list (boolean_type_node, ptr_type_node, ptr_type_node,
- uint64_type_node, boolean_type_node,
- integer_type_node, integer_type_node,
- NULL_TREE);
- this->define_builtin (BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8,
- "__atomic_compare_exchange_8", NULL, t, 0);
-
- t = build_function_type_list (uint32_type_node, ptr_type_node,
- uint32_type_node, integer_type_node, NULL_TREE);
- this->define_builtin (BUILT_IN_ATOMIC_ADD_FETCH_4, "__atomic_add_fetch_4",
- NULL, t, 0);
-
- t = build_function_type_list (uint64_type_node, ptr_type_node,
- uint64_type_node, integer_type_node, NULL_TREE);
- this->define_builtin (BUILT_IN_ATOMIC_ADD_FETCH_8, "__atomic_add_fetch_8",
- NULL, t, 0);
-
- t = build_function_type_list (unsigned_char_type_node, ptr_type_node,
- unsigned_char_type_node, integer_type_node,
- NULL_TREE);
- this->define_builtin (BUILT_IN_ATOMIC_AND_FETCH_1, "__atomic_and_fetch_1",
- NULL, t, 0);
- this->define_builtin (BUILT_IN_ATOMIC_FETCH_AND_1, "__atomic_fetch_and_1",
- NULL, t, 0);
-
- t = build_function_type_list (unsigned_char_type_node, ptr_type_node,
- unsigned_char_type_node, integer_type_node,
- NULL_TREE);
- this->define_builtin (BUILT_IN_ATOMIC_OR_FETCH_1, "__atomic_or_fetch_1", NULL,
- t, 0);
- this->define_builtin (BUILT_IN_ATOMIC_FETCH_OR_1, "__atomic_fetch_or_1", NULL,
- t, 0);
+ // t = build_function_type_list (uint32_type_node, ptr_type_node,
+ // integer_type_node, NULL_TREE);
+ // this->define_builtin (BUILT_IN_ATOMIC_LOAD_4, "__atomic_load_4", NULL, t,
+ // 0);
+
+ // t = build_function_type_list (uint64_type_node, ptr_type_node,
+ // integer_type_node, NULL_TREE);
+ // this->define_builtin (BUILT_IN_ATOMIC_LOAD_8, "__atomic_load_8", NULL, t,
+ // 0);
+
+ // t = build_function_type_list (void_type_node, ptr_type_node,
+ // uint32_type_node,
+ // integer_type_node, NULL_TREE);
+ // this->define_builtin (BUILT_IN_ATOMIC_STORE_4, "__atomic_store_4", NULL, t,
+ // 0);
+
+ // t = build_function_type_list (void_type_node, ptr_type_node,
+ // uint64_type_node,
+ // integer_type_node, NULL_TREE);
+ // this->define_builtin (BUILT_IN_ATOMIC_STORE_8, "__atomic_store_8", NULL, t,
+ // 0);
+
+ // t = build_function_type_list (uint32_type_node, ptr_type_node,
+ // uint32_type_node, integer_type_node, NULL_TREE);
+ // this->define_builtin (BUILT_IN_ATOMIC_EXCHANGE_4, "__atomic_exchange_4",
+ // NULL,
+ // t, 0);
+
+ // t = build_function_type_list (uint64_type_node, ptr_type_node,
+ // uint64_type_node, integer_type_node, NULL_TREE);
+ // this->define_builtin (BUILT_IN_ATOMIC_EXCHANGE_8, "__atomic_exchange_8",
+ // NULL,
+ // t, 0);
+
+ // t = build_function_type_list (boolean_type_node, ptr_type_node,
+ // ptr_type_node,
+ // uint32_type_node, boolean_type_node,
+ // integer_type_node, integer_type_node,
+ // NULL_TREE);
+ // this->define_builtin (BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4,
+ // "__atomic_compare_exchange_4", NULL, t, 0);
+
+ // t = build_function_type_list (boolean_type_node, ptr_type_node,
+ // ptr_type_node,
+ // uint64_type_node, boolean_type_node,
+ // integer_type_node, integer_type_node,
+ // NULL_TREE);
+ // this->define_builtin (BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8,
+ // "__atomic_compare_exchange_8", NULL, t, 0);
+
+ // t = build_function_type_list (uint32_type_node, ptr_type_node,
+ // uint32_type_node, integer_type_node, NULL_TREE);
+ // this->define_builtin (BUILT_IN_ATOMIC_ADD_FETCH_4, "__atomic_add_fetch_4",
+ // NULL, t, 0);
+
+ // t = build_function_type_list (uint64_type_node, ptr_type_node,
+ // uint64_type_node, integer_type_node, NULL_TREE);
+ // this->define_builtin (BUILT_IN_ATOMIC_ADD_FETCH_8, "__atomic_add_fetch_8",
+ // NULL, t, 0);
+
+ // t = build_function_type_list (unsigned_char_type_node, ptr_type_node,
+ // unsigned_char_type_node, integer_type_node,
+ // NULL_TREE);
+ // this->define_builtin (BUILT_IN_ATOMIC_AND_FETCH_1, "__atomic_and_fetch_1",
+ // NULL, t, 0);
+ // this->define_builtin (BUILT_IN_ATOMIC_FETCH_AND_1, "__atomic_fetch_and_1",
+ // NULL, t, 0);
+
+ // t = build_function_type_list (unsigned_char_type_node, ptr_type_node,
+ // unsigned_char_type_node, integer_type_node,
+ // NULL_TREE);
+ // this->define_builtin (BUILT_IN_ATOMIC_OR_FETCH_1, "__atomic_or_fetch_1",
+ // NULL,
+ // t, 0);
+ // this->define_builtin (BUILT_IN_ATOMIC_FETCH_OR_1, "__atomic_fetch_or_1",
+ // NULL,
+ // t, 0);
}
// Get an unnamed integer type.
@@ -3490,13 +3421,23 @@ Gcc_backend::function_set_body (Bfunction *function, Bstatement *code_stmt)
// Returns NULL if no built-in function by that name exists.
Bfunction *
-Gcc_backend::lookup_builtin (const std::string &name)
+Gcc_backend::lookup_gcc_builtin (const std::string &name)
{
if (this->builtin_functions_.count (name) != 0)
return this->builtin_functions_[name];
return NULL;
}
+Bfunction *
+Gcc_backend::lookup_builtin_by_rust_name (const std::string &name)
+{
+ auto it = rust_intrinsic_to_gcc_builtin.find (name);
+ if (it == rust_intrinsic_to_gcc_builtin.end ())
+ return NULL;
+
+ return lookup_gcc_builtin (it->second);
+}
+
// Write the definitions for all TYPE_DECLS, CONSTANT_DECLS,
// FUNCTION_DECLS, and VARIABLE_DECLS declared globally, as well as
// emit early debugging information.
@@ -3587,7 +3528,8 @@ Gcc_backend::write_export_data (const char *bytes, unsigned int size)
// NORETURN_P is true if the function has the noreturn attribute.
void
-Gcc_backend::define_builtin (built_in_function bcode, const char *name,
+Gcc_backend::define_builtin (const std::string rust_name,
+ built_in_function bcode, const char *name,
const char *libname, tree fntype, int flags)
{
tree decl = add_builtin_function (name, fntype, bcode, BUILT_IN_NORMAL,
@@ -3612,6 +3554,8 @@ Gcc_backend::define_builtin (built_in_function bcode, const char *name,
DECL_IS_NOVOPS (decl) = 1;
this->builtin_functions_[libname] = this->make_function (decl);
}
+
+ rust_intrinsic_to_gcc_builtin[rust_name] = name;
}
// Return the backend generator.
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
index 59ea4ef..b1eb2e3 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
@@ -33,9 +33,9 @@ class TypeCheckTopLevelExternItem : public TypeCheckBase
using Rust::Resolver::TypeCheckBase::visit;
public:
- static void Resolve (HIR::ExternalItem *item)
+ static void Resolve (HIR::ExternalItem *item, const HIR::ExternBlock &parent)
{
- TypeCheckTopLevelExternItem resolver;
+ TypeCheckTopLevelExternItem resolver (parent);
item->accept_vis (resolver);
}
@@ -115,16 +115,21 @@ public:
if (function.is_variadic ())
flags |= FNTYPE_IS_VARADIC_FLAG;
- auto fnType
- = new TyTy::FnType (function.get_mappings ().get_hirid (),
- function.get_mappings ().get_defid (),
- function.get_item_name (), flags, std::move (params),
- ret_type, std::move (substitutions));
+ auto fnType = new TyTy::FnType (
+ function.get_mappings ().get_hirid (),
+ function.get_mappings ().get_defid (), function.get_item_name (), flags,
+ TyTy::FnType::get_abi_from_string (parent.get_abi (),
+ parent.get_locus ()),
+ std::move (params), ret_type, std::move (substitutions));
context->insert_type (function.get_mappings (), fnType);
}
private:
- TypeCheckTopLevelExternItem () : TypeCheckBase () {}
+ TypeCheckTopLevelExternItem (const HIR::ExternBlock &parent)
+ : TypeCheckBase (), parent (parent)
+ {}
+
+ const HIR::ExternBlock &parent;
};
class TypeCheckTopLevelImplItem : public TypeCheckBase
@@ -233,11 +238,14 @@ public:
context->insert_type (param.get_mappings (), param_tyty);
}
- auto fnType = new TyTy::FnType (
- function.get_mappings ().get_hirid (),
- function.get_mappings ().get_defid (), function.get_function_name (),
- function.is_method () ? FNTYPE_IS_METHOD_FLAG : FNTYPE_DEFAULT_FLAGS,
- std::move (params), ret_type, std::move (substitutions));
+ auto fnType
+ = new TyTy::FnType (function.get_mappings ().get_hirid (),
+ function.get_mappings ().get_defid (),
+ function.get_function_name (),
+ function.is_method () ? FNTYPE_IS_METHOD_FLAG
+ : FNTYPE_DEFAULT_FLAGS,
+ TyTy::FnType::ABI::RUST, std::move (params), ret_type,
+ std::move (substitutions));
context->insert_type (function.get_mappings (), fnType);
}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.h b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
index 77cbc06..54280e8 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-stmt.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
@@ -329,11 +329,12 @@ public:
context->insert_type (param.get_mappings (), param_tyty);
}
- auto fnType = new TyTy::FnType (function.get_mappings ().get_hirid (),
- function.get_mappings ().get_defid (),
- function.get_function_name (), false,
- std::move (params), ret_type,
- std::move (substitutions));
+ auto fnType
+ = new TyTy::FnType (function.get_mappings ().get_hirid (),
+ function.get_mappings ().get_defid (),
+ function.get_function_name (), FNTYPE_DEFAULT_FLAGS,
+ TyTy::FnType::ABI::RUST, std::move (params), ret_type,
+ std::move (substitutions));
context->insert_type (function.get_mappings (), fnType);
TyTy::FnType *resolved_fn_type = fnType;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
index 5bffe13..6ec17a9 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
@@ -287,11 +287,12 @@ public:
context->insert_type (param.get_mappings (), param_tyty);
}
- auto fnType = new TyTy::FnType (function.get_mappings ().get_hirid (),
- function.get_mappings ().get_defid (),
- function.get_function_name (),
- FNTYPE_DEFAULT_FLAGS, std::move (params),
- ret_type, std::move (substitutions));
+ auto fnType
+ = new TyTy::FnType (function.get_mappings ().get_hirid (),
+ function.get_mappings ().get_defid (),
+ function.get_function_name (), FNTYPE_DEFAULT_FLAGS,
+ TyTy::FnType::ABI::RUST, std::move (params), ret_type,
+ std::move (substitutions));
context->insert_type (function.get_mappings (), fnType);
}
@@ -337,7 +338,7 @@ public:
{
for (auto &item : extern_block.get_extern_items ())
{
- TypeCheckTopLevelExternItem::Resolve (item.get ());
+ TypeCheckTopLevelExternItem::Resolve (item.get (), extern_block);
}
}
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index 453f743..bee2748 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -546,11 +546,12 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
context->insert_type (param.get_mappings (), param_tyty);
}
- auto resolved
- = new TyTy::FnType (fn.get_mappings ().get_hirid (),
- fn.get_mappings ().get_defid (),
- function.get_function_name (), function.is_method (),
- std::move (params), ret_type, substitutions);
+ auto resolved = new TyTy::FnType (
+ fn.get_mappings ().get_hirid (), fn.get_mappings ().get_defid (),
+ function.get_function_name (),
+ function.is_method () ? FNTYPE_IS_METHOD_FLAG : FNTYPE_DEFAULT_FLAGS,
+ TyTy::FnType::ABI::RUST, std::move (params), ret_type, substitutions);
+
context->insert_type (fn.get_mappings (), resolved);
return resolved;
}
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 7eb717f..316caea 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -882,7 +882,7 @@ FnType::clone () const
std::pair<HIR::Pattern *, BaseType *> (p.first, p.second->clone ()));
return new FnType (get_ref (), get_ty_ref (), get_id (), get_identifier (),
- flags, std::move (cloned_params),
+ flags, abi, std::move (cloned_params),
get_return_type ()->clone (), clone_substs (),
get_combined_refs ());
}
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 0dfae37..7f149a9 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -1071,12 +1071,51 @@ private:
class FnType : public BaseType, public SubstitutionRef
{
public:
+ // FIXME these could be constants
#define FNTYPE_DEFAULT_FLAGS 0x00
#define FNTYPE_IS_METHOD_FLAG 0x01
#define FNTYPE_IS_EXTERN_FLAG 0x02
#define FNTYPE_IS_VARADIC_FLAG 0X04
- FnType (HirId ref, DefId id, std::string identifier, uint8_t flags,
+ enum ABI
+ {
+ UNKNOWN,
+ RUST,
+ INTRINSIC,
+ C,
+ };
+
+ static ABI get_abi_from_string (const std::string &abi, Location locus)
+ {
+ if (abi.compare ("rust") == 0)
+ return ABI::C;
+ else if (abi.compare ("rust-intrinsic") == 0)
+ return ABI::INTRINSIC;
+ else if (abi.compare ("C") == 0)
+ return ABI::C;
+
+ rust_error_at (locus, "unknown abi specified");
+ return ABI::UNKNOWN;
+ }
+
+ static std::string get_string_from_abi (ABI abi)
+ {
+ switch (abi)
+ {
+ case ABI::RUST:
+ return "rust";
+ case ABI::INTRINSIC:
+ return "rust-intrinsic";
+ case ABI::C:
+ return "C";
+
+ case ABI::UNKNOWN:
+ return "unknown";
+ }
+ return "unknown";
+ }
+
+ FnType (HirId ref, DefId id, std::string identifier, uint8_t flags, ABI abi,
std::vector<std::pair<HIR::Pattern *, BaseType *>> params,
BaseType *type, std::vector<SubstitutionParamMapping> subst_refs,
std::set<HirId> refs = std::set<HirId> ())
@@ -1084,14 +1123,14 @@ public:
SubstitutionRef (std::move (subst_refs),
SubstitutionArgumentMappings::error ()),
params (std::move (params)), type (type), flags (flags),
- identifier (identifier), id (id)
+ identifier (identifier), id (id), abi (abi)
{
LocalDefId local_def_id = id & DEF_ID_LOCAL_DEF_MASK;
rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
}
FnType (HirId ref, HirId ty_ref, DefId id, std::string identifier,
- uint8_t flags,
+ uint8_t flags, ABI abi,
std::vector<std::pair<HIR::Pattern *, BaseType *>> params,
BaseType *type, std::vector<SubstitutionParamMapping> subst_refs,
std::set<HirId> refs = std::set<HirId> ())
@@ -1099,7 +1138,7 @@ public:
SubstitutionRef (std::move (subst_refs),
SubstitutionArgumentMappings::error ()),
params (params), type (type), flags (flags), identifier (identifier),
- id (id)
+ id (id), abi (abi)
{
LocalDefId local_def_id = id & DEF_ID_LOCAL_DEF_MASK;
rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
@@ -1184,12 +1223,15 @@ public:
FnType *
handle_substitions (SubstitutionArgumentMappings mappings) override final;
+ ABI get_abi () const { return abi; }
+
private:
std::vector<std::pair<HIR::Pattern *, BaseType *>> params;
BaseType *type;
uint8_t flags;
std::string identifier;
DefId id;
+ ABI abi;
};
class FnPtr : public BaseType
diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-1.rs b/gcc/testsuite/rust/compile/torture/intrinsics-1.rs
new file mode 100644
index 0000000..3c604df
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/intrinsics-1.rs
@@ -0,0 +1,16 @@
+// { dg-additional-options -fdump-tree-original }
+
+extern "rust-intrinsic" {
+ pub fn sqrtf32(x: f32) -> f32;
+ pub fn sinf32(x: f32) -> f32;
+}
+
+fn main() {
+ let mut f32;
+
+ f32 = sqrtf32(5f32);
+ // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_sqrtf \(5\.0e\+0\);$} 1 original } }
+
+ f32 = sinf32(39f32);
+ // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_sinf \(3\.9e\+1\);$} 1 original } }
+}