Skip to content

Commit 68b5bbc

Browse files
committed
Fix u128 rotate operation on 32 bit targets
gcc/rust/ChangeLog: * backend/rust-compile-intrinsic.cc: Include "convert.h". (rotate_handler): Convert the second parameter into an unsigned int. * rust-backend.h (rust_int_trees): Declare extern variable. (rust_int_names): Likewise. * rust-gcc.cc: Include "target.h". (rust_int_trees): Define variable. (rust_int_names): Likewise. (setup_normal_integers): Define static function. (init): Call setup_normal_integers. * backend/rust-compile-type.cc (TyTyResolveCompile::visit): Use rust_int_trees to obtain integer type trees. gcc/testsuite/ChangeLog: * rust/execute/torture/sip-hasher.rs: Enable on 32 bit targets. Signed-off-by: Owen Avery <[email protected]>
1 parent 3a57c56 commit 68b5bbc

File tree

5 files changed

+119
-27
lines changed

5 files changed

+119
-27
lines changed

gcc/rust/backend/rust-compile-intrinsic.cc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "rust-gcc.h"
2929
#include "fold-const.h"
3030
#include "langhooks.h"
31+
#include "convert.h"
3132
#include "rust-constexpr.h"
3233

3334
// declaration taken from "stringpool.h"
@@ -557,8 +558,16 @@ rotate_handler (Context *ctx, TyTy::FnType *fntype, tree_code op)
557558
// BUILTIN rotate FN BODY BEGIN
558559
tree x = Backend::var_expression (x_param, UNDEF_LOCATION);
559560
tree y = Backend::var_expression (y_param, UNDEF_LOCATION);
561+
562+
tree y_mask
563+
= build_int_cst (unsigned_type_node, TYPE_SIZE (TREE_TYPE (x)) - 1);
564+
565+
tree y_truncated
566+
= fold_build2_loc (BUILTINS_LOCATION, BIT_AND_EXPR, unsigned_type_node,
567+
convert_to_integer (unsigned_type_node, y), y_mask);
568+
560569
tree rotate_expr
561-
= fold_build2_loc (BUILTINS_LOCATION, op, TREE_TYPE (x), x, y);
570+
= fold_build2_loc (BUILTINS_LOCATION, op, TREE_TYPE (x), x, y_truncated);
562571
auto return_statement
563572
= Backend::return_statement (fndecl, rotate_expr, UNDEF_LOCATION);
564573
ctx->add_statement (return_statement);

gcc/rust/backend/rust-compile-type.cc

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -504,32 +504,23 @@ TyTyResolveCompile::visit (const TyTy::IntType &type)
504504
switch (type.get_int_kind ())
505505
{
506506
case TyTy::IntType::I8:
507-
translated = Backend::named_type ("i8", Backend::integer_type (false, 8),
508-
BUILTINS_LOCATION);
507+
translated = Backend::rust_int_trees[5];
509508
return;
510509

511510
case TyTy::IntType::I16:
512-
translated
513-
= Backend::named_type ("i16", Backend::integer_type (false, 16),
514-
BUILTINS_LOCATION);
511+
translated = Backend::rust_int_trees[6];
515512
return;
516513

517514
case TyTy::IntType::I32:
518-
translated
519-
= Backend::named_type ("i32", Backend::integer_type (false, 32),
520-
BUILTINS_LOCATION);
515+
translated = Backend::rust_int_trees[7];
521516
return;
522517

523518
case TyTy::IntType::I64:
524-
translated
525-
= Backend::named_type ("i64", Backend::integer_type (false, 64),
526-
BUILTINS_LOCATION);
519+
translated = Backend::rust_int_trees[8];
527520
return;
528521

529522
case TyTy::IntType::I128:
530-
translated
531-
= Backend::named_type ("i128", Backend::integer_type (false, 128),
532-
BUILTINS_LOCATION);
523+
translated = Backend::rust_int_trees[9];
533524
return;
534525
}
535526
}
@@ -540,29 +531,23 @@ TyTyResolveCompile::visit (const TyTy::UintType &type)
540531
switch (type.get_uint_kind ())
541532
{
542533
case TyTy::UintType::U8:
543-
translated = Backend::named_type ("u8", Backend::integer_type (true, 8),
544-
BUILTINS_LOCATION);
534+
translated = Backend::rust_int_trees[0];
545535
return;
546536

547537
case TyTy::UintType::U16:
548-
translated = Backend::named_type ("u16", Backend::integer_type (true, 16),
549-
BUILTINS_LOCATION);
538+
translated = Backend::rust_int_trees[1];
550539
return;
551540

552541
case TyTy::UintType::U32:
553-
translated = Backend::named_type ("u32", Backend::integer_type (true, 32),
554-
BUILTINS_LOCATION);
542+
translated = Backend::rust_int_trees[2];
555543
return;
556544

557545
case TyTy::UintType::U64:
558-
translated = Backend::named_type ("u64", Backend::integer_type (true, 64),
559-
BUILTINS_LOCATION);
546+
translated = Backend::rust_int_trees[3];
560547
return;
561548

562549
case TyTy::UintType::U128:
563-
translated
564-
= Backend::named_type ("u128", Backend::integer_type (true, 128),
565-
BUILTINS_LOCATION);
550+
translated = Backend::rust_int_trees[4];
566551
return;
567552
}
568553
}

gcc/rust/rust-backend.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ using Rust::GGC::Ident;
5050

5151
} // namespace GGC
5252

53+
extern tree rust_int_trees[10];
54+
extern const char *rust_int_names[10];
55+
5356
void init ();
5457

5558
// Name/type/location. Used for function parameters, struct fields,

gcc/rust/rust-gcc.cc

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include "builtins.h"
4646
#include "print-tree.h"
4747
#include "attribs.h"
48+
#include "target.h"
4849

4950
#include "rust-location.h"
5051
#include "rust-linemap.h"
@@ -95,9 +96,104 @@ namespace Backend {
9596

9697
// Define the built-in functions that are exposed to GCCRust.
9798

99+
// (u, i) X (8, 16, 32, 64, 128)
100+
tree rust_int_trees[10];
101+
const char *rust_int_names[10]
102+
= {"u8", "u16", "u32", "u64", "u128", "i8", "i16", "i32", "i64", "i128"};
103+
104+
static void
105+
setup_normal_integers ()
106+
{
107+
// we should have QImode
108+
rust_int_trees[0] = make_unsigned_type (8);
109+
rust_int_trees[5] = make_signed_type (8);
110+
111+
// look through integer types intended for C
112+
const int normal_int_sizes[4]
113+
= {INT_TYPE_SIZE, SHORT_TYPE_SIZE, LONG_TYPE_SIZE, LONG_LONG_TYPE_SIZE};
114+
const tree normal_int_trees[8]
115+
= {unsigned_type_node, integer_type_node,
116+
short_unsigned_type_node, short_integer_type_node,
117+
long_unsigned_type_node, long_integer_type_node,
118+
long_long_unsigned_type_node, long_long_integer_type_node};
119+
120+
for (size_t i = 0; i < 4; i++)
121+
{
122+
// check for a power of 2 or 0
123+
if (normal_int_sizes[i] & (normal_int_sizes[i] - 1))
124+
continue;
125+
126+
// assume size is not 0
127+
int idx = __builtin_ctz (normal_int_sizes[i]) - 3;
128+
if (idx < 0 || idx > 5)
129+
continue;
130+
131+
if (rust_int_trees[idx] != NULL_TREE)
132+
continue;
133+
134+
rust_int_trees[idx] = normal_int_trees[2 * i];
135+
rust_int_trees[5 + idx] = normal_int_trees[2 * i + 1];
136+
}
137+
138+
// look through int_n_data for more integer types
139+
for (size_t i = 0, j = 0; i < 5 && j < NUM_INT_N_ENTS;)
140+
{
141+
if (rust_int_trees[i] != NULL_TREE)
142+
{
143+
i++;
144+
continue;
145+
}
146+
147+
if (!int_n_enabled_p[j] || int_n_data[j].bitsize < (8u << i))
148+
{
149+
j++;
150+
}
151+
else if (int_n_data[j].bitsize > (8u << i))
152+
{
153+
i++;
154+
}
155+
else
156+
{
157+
rust_int_trees[i] = make_unsigned_type (8 << i);
158+
rust_int_trees[5 + i] = make_signed_type (8 << i);
159+
i++;
160+
j++;
161+
}
162+
}
163+
164+
// use _BitInt where we have to (and can)
165+
for (int i = 0; i < 5; i++)
166+
{
167+
if (rust_int_trees[i] == NULL_TREE)
168+
{
169+
bitint_info b_info;
170+
if (targetm.c.bitint_type_info (8 << i, &b_info))
171+
{
172+
rust_debug ("filling in integer size %u with _BitInt", 8u << i);
173+
rust_int_trees[i] = build_bitint_type (8 << i, true);
174+
rust_int_trees[5 + i] = build_bitint_type (8 << i, false);
175+
}
176+
}
177+
}
178+
179+
// TODO: bootleg _BitInt where necessary?
180+
181+
// not much can be done for now -- fill with error_mark_node
182+
for (size_t i = 0; i < 10; i++)
183+
if (rust_int_trees[i] == NULL_TREE)
184+
rust_int_trees[i] = error_mark_node;
185+
186+
// name types
187+
for (size_t i = 0; i < 10; i++)
188+
rust_int_trees[i]
189+
= named_type (rust_int_names[i], rust_int_trees[i], BUILTINS_LOCATION);
190+
}
191+
98192
void
99193
init ()
100194
{
195+
setup_normal_integers ();
196+
101197
/* We need to define the fetch_and_add functions, since we use them
102198
for ++ and --. */
103199
// tree t = this->integer_type (true, BITS_PER_UNIT)->get_tree ();

gcc/testsuite/rust/execute/torture/sip-hasher.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// { dg-skip-if "" { *-*-* } { "-m32" } { "" } }
21
// { dg-options "-w" }
32
// { dg-output "Hash: 0x63d53fd2170bbb8c\r*\n" }
43
#![feature(intrinsics)]

0 commit comments

Comments
 (0)