From 1c586a1d1c12dce2a65fb117b577a73ad5cf45ea Mon Sep 17 00:00:00 2001 From: Arthur Cohen Date: Wed, 26 Oct 2022 15:57:54 +0200 Subject: gccrs: intrinsics: Add unchecked operation intrinsics gcc/rust/ChangeLog: * backend/rust-compile-intrinsic.cc (is_basic_integer_type): New function. (unchecked_op_inner): New handler. (unchecked_op_handler): New handler. gcc/testsuite/ChangeLog: * rust/compile/torture/intrinsics-6.rs: New test. * rust/compile/torture/intrinsics-7.rs: New test. --- gcc/rust/backend/rust-compile-intrinsic.cc | 80 ++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) (limited to 'gcc/rust') diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc index 7c592da..46ea5b3 100644 --- a/gcc/rust/backend/rust-compile-intrinsic.cc +++ b/gcc/rust/backend/rust-compile-intrinsic.cc @@ -34,6 +34,22 @@ namespace Rust { namespace Compile { +static bool +is_basic_integer_type (TyTy::BaseType *type) +{ + switch (type->get_kind ()) + { + case TyTy::INT: + case TyTy::UINT: + case TyTy::USIZE: + case TyTy::ISIZE: + return true; + default: + return false; + break; + } +} + static tree offset_handler (Context *ctx, TyTy::FnType *fntype); static tree @@ -105,6 +121,17 @@ atomic_store_handler (int ordering) } static inline tree +unchecked_op_inner (Context *ctx, TyTy::FnType *fntype, tree_code op); + +const static std::function +unchecked_op_handler (tree_code op) +{ + return [op] (Context *ctx, TyTy::FnType *fntype) { + return unchecked_op_inner (ctx, fntype, op); + }; +} + +static inline tree sorry_handler (Context *ctx, TyTy::FnType *fntype) { rust_sorry_at (fntype->get_locus (), "intrinsic %qs is not yet implemented", @@ -132,6 +159,13 @@ static const std::mapadd_statement (store_call); + finalize_intrinsic_block (ctx, fndecl); + + return fndecl; +} + +static inline tree +unchecked_op_inner (Context *ctx, TyTy::FnType *fntype, tree_code op) +{ + rust_assert (fntype->get_params ().size () == 2); + rust_assert (fntype->get_num_substitutions () == 1); + + tree lookup = NULL_TREE; + if (check_for_cached_intrinsic (ctx, fntype, &lookup)) + return lookup; + + auto fndecl = compile_intrinsic_function (ctx, fntype); + + // setup the params + std::vector param_vars; + compile_fn_params (ctx, fntype, fndecl, ¶m_vars); + + if (!ctx->get_backend ()->function_set_parameters (fndecl, param_vars)) + return error_mark_node; + + enter_intrinsic_block (ctx, fndecl); + + // BUILTIN unchecked_ BODY BEGIN + + auto x = ctx->get_backend ()->var_expression (param_vars[0], Location ()); + auto y = ctx->get_backend ()->var_expression (param_vars[1], Location ()); + + auto *monomorphized_type + = fntype->get_substs ().at (0).get_param_ty ()->resolve (); + if (!is_basic_integer_type (monomorphized_type)) + rust_error_at (fntype->get_locus (), + "unchecked operation intrinsics can only be used with " + "basic integer types (got %qs)", + monomorphized_type->get_name ().c_str ()); + + auto expr = build2 (op, TREE_TYPE (x), x, y); + auto return_statement + = ctx->get_backend ()->return_statement (fndecl, {expr}, Location ()); + + ctx->add_statement (return_statement); + + // BUILTIN unchecked_ BODY END finalize_intrinsic_block (ctx, fndecl); -- cgit v1.1