Skip to content

[WIP] Enable 128 bit integers on 32 bit targets #4009

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion gcc/rust/backend/rust-compile-intrinsic.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand Down
35 changes: 10 additions & 25 deletions gcc/rust/backend/rust-compile-type.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand All @@ -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;
}
}
Expand Down
1 change: 1 addition & 0 deletions gcc/rust/config-lang.in
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
"
17 changes: 17 additions & 0 deletions gcc/rust/rust-backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
94 changes: 94 additions & 0 deletions gcc/rust/rust-gcc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand All @@ -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 ();
Expand Down
1 change: 0 additions & 1 deletion gcc/testsuite/rust/execute/torture/sip-hasher.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// { dg-skip-if "" { *-*-* } { "-m32" } { "" } }
// { dg-options "-w" }
// { dg-output "Hash: 0x63d53fd2170bbb8c\r*\n" }
#![feature(intrinsics)]
Expand Down
Loading