@@ -92,6 +92,8 @@ static tree
92
92
move_val_init_handler (Context *ctx, TyTy::FnType *fntype);
93
93
static tree
94
94
assume_handler (Context *ctx, TyTy::FnType *fntype);
95
+ static tree
96
+ ctpop_hander (Context *ctx, TyTy::FnType *fntype);
95
97
96
98
enum class Prefetch
97
99
{
@@ -241,6 +243,7 @@ static const std::map<std::string,
241
243
{" likely" , expect_handler (true )},
242
244
{" unlikely" , expect_handler (false )},
243
245
{" assume" , assume_handler},
246
+ {" ctpop" , ctpop_hander},
244
247
};
245
248
246
249
Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {}
@@ -611,6 +614,67 @@ wrapping_op_handler_inner (Context *ctx, TyTy::FnType *fntype, tree_code op)
611
614
return fndecl;
612
615
}
613
616
617
+ static tree
618
+ ctpop_hander (Context *ctx, TyTy::FnType *fntype)
619
+ {
620
+ rust_assert (fntype->get_params ().size () == 1 );
621
+
622
+ tree lookup = NULL_TREE;
623
+ if (check_for_cached_intrinsic (ctx, fntype, &lookup))
624
+ return lookup;
625
+
626
+ auto fndecl = compile_intrinsic_function (ctx, fntype);
627
+
628
+ // setup the params
629
+ std::vector<Bvariable *> param_vars;
630
+ compile_fn_params (ctx, fntype, fndecl, ¶m_vars);
631
+
632
+ auto &x_param = param_vars.at (0 );
633
+
634
+ if (!Backend::function_set_parameters (fndecl, param_vars))
635
+ return error_mark_node;
636
+
637
+ rust_assert (fntype->get_num_substitutions () == 1 );
638
+ auto ¶m_mapping = fntype->get_substs ().at (0 );
639
+ const TyTy::ParamType *param_tyty = param_mapping.get_param_ty ();
640
+ TyTy::BaseType *resolved_tyty = param_tyty->resolve ();
641
+ tree template_parameter_type
642
+ = TyTyResolveCompile::compile (ctx, resolved_tyty);
643
+
644
+ tree tmp_stmt = error_mark_node;
645
+ Bvariable *result_variable
646
+ = Backend::temporary_variable (fndecl, NULL_TREE, template_parameter_type,
647
+ NULL_TREE, true /* address_is_taken*/ ,
648
+ UNDEF_LOCATION, &tmp_stmt);
649
+
650
+ enter_intrinsic_block (ctx, fndecl, {result_variable});
651
+
652
+ // BUILTIN popcount FN BODY BEGIN
653
+ auto x = Backend::var_expression (x_param, UNDEF_LOCATION);
654
+
655
+ tree popcount_builtin = error_mark_node;
656
+
657
+ BuiltinsContext::get ().lookup_simple_builtin (" __builtin_popcountg" ,
658
+ &popcount_builtin);
659
+ rust_assert (popcount_builtin != error_mark_node);
660
+
661
+ tree builtin_call
662
+ = build_call_expr_loc (BUILTINS_LOCATION, popcount_builtin, 1 , x);
663
+
664
+ auto return_statement
665
+ = Backend::return_statement (fndecl,
666
+ build1 (CONVERT_EXPR, unsigned_type_node,
667
+ builtin_call),
668
+ UNDEF_LOCATION);
669
+ ctx->add_statement (return_statement);
670
+
671
+ // BUILTIN popcount FN BODY END
672
+
673
+ finalize_intrinsic_block (ctx, fndecl);
674
+
675
+ return fndecl;
676
+ }
677
+
614
678
/* *
615
679
* pub fn add_with_overflow<T>(x: T, y: T) -> (T, bool);
616
680
*/
0 commit comments