Skip to content

Commit 313ec2d

Browse files
committed
Add conversion for rol and ror operators to c output
This adds conversion for the rol and ror operators from CBMC internals into C code. This is done by bit-twiddling the values to achieve the outcome. Fixes #6241
1 parent d5c9ef8 commit 313ec2d

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

src/ansi-c/expr2c.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3794,6 +3794,59 @@ std::string expr2ct::convert_with_precedence(
37943794
else if(src.id()==ID_type)
37953795
return convert(src.type());
37963796

3797+
else if(src.id() == ID_rol)
3798+
{
3799+
// TODO:
3800+
// 1. check RHS is >= 0 && < LHS.type.width
3801+
// Can be done with bitmasks...
3802+
// 2. handle signed types: convert to unsigned, rotate, convert back
3803+
// AAAA rol n == (AAAA << n) | (AAAA >> (width(AAAA) - n))
3804+
auto bin_expr = to_binary_expr(src);
3805+
const exprt &op0 = bin_expr.op0();
3806+
const exprt &op1 = bin_expr.op1();
3807+
irep_idt width_val = op0.type().get("width");
3808+
// if(can_cast_type<signedbv_typet>(op0.type()))
3809+
// {
3810+
// // Do something
3811+
// }
3812+
auto width = constant_exprt(width_val, op1.type());
3813+
auto complement_expr = minus_exprt(width, op1);
3814+
auto rhs_expr = ashr_exprt(op0, complement_expr);
3815+
// if(can_cast_type<signedbv_typet>(op0.type()))
3816+
// {
3817+
// // (Un)Do something
3818+
// }
3819+
auto lhs_exprt = shl_exprt(op0, op1);
3820+
auto the_expr = bitor_exprt(lhs_exprt, rhs_expr);
3821+
return convert_with_precedence(the_expr, precedence);
3822+
}
3823+
else if(src.id() == ID_ror)
3824+
{
3825+
// TODO:
3826+
// 1. check RHS is >= 0 && < LHS.type.width
3827+
// Can be done with bitmasks...
3828+
// 2. handle signed types: convert to unsigned, rotate, convert back
3829+
// AAAA ror n == (AAAA >> n) | (AAAA << (width(AAAA) - n))
3830+
auto bin_expr = to_binary_expr(src);
3831+
const exprt &op0 = bin_expr.op0();
3832+
const exprt &op1 = bin_expr.op1();
3833+
irep_idt width_val = op0.type().get("width");
3834+
// if(can_cast_type<signedbv_typet>(op0.type()))
3835+
// {
3836+
// // Do something
3837+
// }
3838+
auto width = constant_exprt(width_val, op1.type());
3839+
auto complement_expr = minus_exprt(width, op1);
3840+
auto rhs_expr = shl_exprt(op0, complement_expr);
3841+
// if(can_cast_type<signedbv_typet>(op0.type()))
3842+
// {
3843+
// // (Un)Do something
3844+
// }
3845+
auto lhs_exprt = ashr_exprt(op0, op1);
3846+
auto the_expr = bitor_exprt(lhs_exprt, rhs_expr);
3847+
return convert_with_precedence(the_expr, precedence);
3848+
}
3849+
37973850
auto function_string_opt = convert_function(src);
37983851
if(function_string_opt.has_value())
37993852
return *function_string_opt;

0 commit comments

Comments
 (0)