diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc index 7627620c471..b790c785478 100644 --- a/gcc/rust/backend/rust-compile-intrinsic.cc +++ b/gcc/rust/backend/rust-compile-intrinsic.cc @@ -28,6 +28,7 @@ #include "rust-gcc.h" #include "fold-const.h" #include "langhooks.h" +#include "convert.h" #include "rust-constexpr.h" // declaration taken from "stringpool.h" @@ -557,8 +558,16 @@ rotate_handler (Context *ctx, TyTy::FnType *fntype, tree_code op) // BUILTIN rotate FN BODY BEGIN tree x = Backend::var_expression (x_param, UNDEF_LOCATION); tree y = Backend::var_expression (y_param, UNDEF_LOCATION); + + tree y_mask + = build_int_cst (unsigned_type_node, element_precision (TREE_TYPE (x)) - 1); + + tree y_truncated + = fold_build2_loc (BUILTINS_LOCATION, BIT_AND_EXPR, unsigned_type_node, + convert_to_integer (unsigned_type_node, y), y_mask); + tree rotate_expr - = fold_build2_loc (BUILTINS_LOCATION, op, TREE_TYPE (x), x, y); + = fold_build2_loc (BUILTINS_LOCATION, op, TREE_TYPE (x), x, y_truncated); auto return_statement = Backend::return_statement (fndecl, rotate_expr, UNDEF_LOCATION); ctx->add_statement (return_statement); diff --git a/gcc/rust/backend/rust-compile-type.cc b/gcc/rust/backend/rust-compile-type.cc index 8f13bba534b..56c23b23e7c 100644 --- a/gcc/rust/backend/rust-compile-type.cc +++ b/gcc/rust/backend/rust-compile-type.cc @@ -504,32 +504,23 @@ TyTyResolveCompile::visit (const TyTy::IntType &type) switch (type.get_int_kind ()) { case TyTy::IntType::I8: - translated = Backend::named_type ("i8", Backend::integer_type (false, 8), - BUILTINS_LOCATION); + translated = RUST_INT_TREE_I8; return; case TyTy::IntType::I16: - translated - = Backend::named_type ("i16", Backend::integer_type (false, 16), - BUILTINS_LOCATION); + translated = RUST_INT_TREE_I16; return; case TyTy::IntType::I32: - translated - = Backend::named_type ("i32", Backend::integer_type (false, 32), - BUILTINS_LOCATION); + translated = RUST_INT_TREE_I32; return; case TyTy::IntType::I64: - translated - = Backend::named_type ("i64", Backend::integer_type (false, 64), - BUILTINS_LOCATION); + translated = RUST_INT_TREE_I64; return; case TyTy::IntType::I128: - translated - = Backend::named_type ("i128", Backend::integer_type (false, 128), - BUILTINS_LOCATION); + translated = RUST_INT_TREE_I128; return; } } @@ -540,29 +531,23 @@ TyTyResolveCompile::visit (const TyTy::UintType &type) switch (type.get_uint_kind ()) { case TyTy::UintType::U8: - translated = Backend::named_type ("u8", Backend::integer_type (true, 8), - BUILTINS_LOCATION); + translated = RUST_INT_TREE_U8; return; case TyTy::UintType::U16: - translated = Backend::named_type ("u16", Backend::integer_type (true, 16), - BUILTINS_LOCATION); + translated = RUST_INT_TREE_U16; return; case TyTy::UintType::U32: - translated = Backend::named_type ("u32", Backend::integer_type (true, 32), - BUILTINS_LOCATION); + translated = RUST_INT_TREE_U32; return; case TyTy::UintType::U64: - translated = Backend::named_type ("u64", Backend::integer_type (true, 64), - BUILTINS_LOCATION); + translated = RUST_INT_TREE_U64; return; case TyTy::UintType::U128: - translated - = Backend::named_type ("u128", Backend::integer_type (true, 128), - BUILTINS_LOCATION); + translated = RUST_INT_TREE_U128; return; } } diff --git a/gcc/rust/config-lang.in b/gcc/rust/config-lang.in index 0ded57052b5..71457cb9790 100644 --- a/gcc/rust/config-lang.in +++ b/gcc/rust/config-lang.in @@ -35,4 +35,5 @@ lang_dirs=libgrust gtfiles="\ \$(srcdir)/rust/rust-lang.cc \$(srcdir)/rust/backend/rust-constexpr.cc \ \$(srcdir)/rust/backend/rust-tree.h \$(srcdir)/rust/backend/rust-tree.cc \ +\$(srcdir)/rust/rust-backend.h \ " diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h index 8a77d96de83..691ca567ef1 100644 --- a/gcc/rust/rust-backend.h +++ b/gcc/rust/rust-backend.h @@ -39,6 +39,23 @@ // The backend representation of a variable. class Bvariable; +// rust integer trees + +#define RUST_INT_TREE_U8 (rust_int_trees[0]) +#define RUST_INT_TREE_U16 (rust_int_trees[1]) +#define RUST_INT_TREE_U32 (rust_int_trees[2]) +#define RUST_INT_TREE_U64 (rust_int_trees[3]) +#define RUST_INT_TREE_U128 (rust_int_trees[4]) + +#define RUST_INT_TREE_I8 (rust_int_trees[5]) +#define RUST_INT_TREE_I16 (rust_int_trees[6]) +#define RUST_INT_TREE_I32 (rust_int_trees[7]) +#define RUST_INT_TREE_I64 (rust_int_trees[8]) +#define RUST_INT_TREE_I128 (rust_int_trees[9]) + +extern GTY (()) tree rust_int_trees[10]; +extern const char *rust_int_names[10]; + // The backend interface. This is a pure abstract class that a // specific backend will implement. diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc index c5fda5c7a9c..30584967239 100644 --- a/gcc/rust/rust-gcc.cc +++ b/gcc/rust/rust-gcc.cc @@ -45,6 +45,7 @@ #include "builtins.h" #include "print-tree.h" #include "attribs.h" +#include "target.h" #include "rust-location.h" #include "rust-linemap.h" @@ -83,6 +84,11 @@ Bvariable::error_variable () return new Bvariable (error_mark_node); } +// (u, i) X (8, 16, 32, 64, 128) +tree rust_int_trees[10]; +const char *rust_int_names[10] + = {"u8", "u16", "u32", "u64", "u128", "i8", "i16", "i32", "i64", "i128"}; + // This file implements the interface between the Rust frontend proper // and the gcc IR. This implements specific instantiations of // abstract classes defined by the Rust frontend proper. The Rust @@ -95,9 +101,97 @@ namespace Backend { // Define the built-in functions that are exposed to GCCRust. +static void +setup_normal_integers () +{ + // we should have QImode + RUST_INT_TREE_U8 = make_unsigned_type (8); + RUST_INT_TREE_I8 = make_signed_type (8); + + // look through integer types intended for C + const int normal_int_sizes[4] + = {INT_TYPE_SIZE, SHORT_TYPE_SIZE, LONG_TYPE_SIZE, LONG_LONG_TYPE_SIZE}; + const tree normal_int_trees[8] + = {unsigned_type_node, integer_type_node, + short_unsigned_type_node, short_integer_type_node, + long_unsigned_type_node, long_integer_type_node, + long_long_unsigned_type_node, long_long_integer_type_node}; + + for (size_t i = 0; i < 4; i++) + { + int idx = exact_log2 (normal_int_sizes[i]) - 3; + + // if the size wasn't a power of 2, idx == -4 + + if (idx < 0 || idx > 5) + continue; + + if (rust_int_trees[idx] != NULL_TREE) + continue; + + rust_int_trees[idx] = normal_int_trees[2 * i]; + rust_int_trees[5 + idx] = normal_int_trees[2 * i + 1]; + } + + // look through int_n_data for more integer types + for (size_t i = 0, j = 0; i < 5 && j < NUM_INT_N_ENTS;) + { + if (rust_int_trees[i] != NULL_TREE) + { + i++; + continue; + } + + if (!int_n_enabled_p[j] || int_n_data[j].bitsize < (8u << i)) + { + j++; + } + else if (int_n_data[j].bitsize > (8u << i)) + { + i++; + } + else + { + rust_int_trees[i] = make_unsigned_type (8 << i); + rust_int_trees[5 + i] = make_signed_type (8 << i); + i++; + j++; + } + } + + // use _BitInt where we have to (and can) + for (int i = 0; i < 5; i++) + { + if (rust_int_trees[i] == NULL_TREE) + { + bitint_info b_info; + if (targetm.c.bitint_type_info (8 << i, &b_info)) + { + rust_debug ("filling in integer size %u with _BitInt", 8u << i); + rust_int_trees[i] = build_bitint_type (8 << i, true); + rust_int_trees[5 + i] = build_bitint_type (8 << i, false); + } + } + } + + // TODO: bootleg _BitInt where necessary? + + // not much can be done for now -- fill with error_mark_node + for (size_t i = 0; i < 10; i++) + if (rust_int_trees[i] == NULL_TREE) + rust_int_trees[i] = error_mark_node; + + // name types + for (size_t i = 0; i < 10; i++) + rust_int_trees[i] + = named_type (rust_int_names[i], rust_int_trees[i], BUILTINS_LOCATION); +} + void init () { + setup_normal_integers (); + /* 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 (); diff --git a/gcc/testsuite/rust/execute/torture/sip-hasher.rs b/gcc/testsuite/rust/execute/torture/sip-hasher.rs index 60826a3ed01..671f69601c0 100644 --- a/gcc/testsuite/rust/execute/torture/sip-hasher.rs +++ b/gcc/testsuite/rust/execute/torture/sip-hasher.rs @@ -1,4 +1,3 @@ -// { dg-skip-if "" { *-*-* } { "-m32" } { "" } } // { dg-options "-w" } // { dg-output "Hash: 0x63d53fd2170bbb8c\r*\n" } #![feature(intrinsics)]