Skip to content

Commit c764708

Browse files
committed
---
yaml --- r: 83309 b: refs/heads/variant-submodule c: c750f5e h: refs/heads/develop i: 83307: 4ebdcd6
1 parent 3ebc3f8 commit c764708

File tree

4 files changed

+80
-2
lines changed

4 files changed

+80
-2
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ refs/heads/unwind-counters4: 57aedaa3fe3995b30ba69c96c9f04df79f8e8ff8
131131
refs/heads/value-set-make-member: 0f8404cb460f55d43bc253e12f1bde7fd7ed4d37
132132
refs/heads/value-set-member-fix: 2c87bd4c0d9e1954e2de6af0118fa1ef296ae548
133133
"refs/heads/value_set_fi_hacks": 3d243543adb4ff450596e7994e2fa1d590ec1e1b
134-
refs/heads/variant-submodule: 5d4b7803c1bf2002fc0f367920e89ac6b04b2a84
134+
refs/heads/variant-submodule: c750f5e9eec033096f42e04518a9f6591a9cc105
135135
refs/heads/windows-console-streambuf: b984ac7bd772da956bb5656f0072d85b3fdbbf34
136136
refs/tags/cbmc-5.10: 097cf712f57d59cff9c53a9fb7b9b81be1245f93
137137
refs/tags/cbmc-5.11: 90d0de91b0918c9e5d5ed250cae62241ae38392a

branches/variant-submodule/src/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ memory-analyzer.dir: util.dir goto-programs.dir langapi.dir linking.dir \
9191
ansi-c.dir
9292

9393
symtab2gb.dir: util.dir goto-programs.dir langapi.dir linking.dir \
94-
json.dir json-symtab-language.dir ansi-c.dir
94+
json.dir json-symtab-language.dir
9595

9696
# building for a particular directory
9797

branches/variant-submodule/src/ansi-c/expr2c.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2290,6 +2290,72 @@ std::string expr2ct::convert_initializer_list(const exprt &src)
22902290
return dest;
22912291
}
22922292

2293+
std::string expr2ct::convert_rox(const exprt &src, unsigned precedence)
2294+
{
2295+
// AAAA rox n == (AAAA lhs_op n % width(AAAA))
2296+
// | (AAAA rhs_op (width(AAAA) - n % width(AAAA)))
2297+
// Where lhs_op and rhs_op depend on whether it is rol or ror
2298+
// auto rotate_expr = to_binary_expr(src);
2299+
auto rotate_expr = expr_checked_cast<shift_exprt>(src);
2300+
// Get AAAA and if it's signed wrap it in a cast to remove
2301+
// the sign since this messes with C shifts
2302+
exprt &op0 = rotate_expr.op();
2303+
size_t type_width;
2304+
if(can_cast_type<signedbv_typet>(op0.type()))
2305+
{
2306+
// Set the type width
2307+
type_width = to_signedbv_type(op0.type()).get_width();
2308+
// Shifts in C are arithmetic and care about sign, by forcing
2309+
// a cast to unsigned we force the shifts to perform rol/r
2310+
op0 = typecast_exprt(op0, unsignedbv_typet(type_width));
2311+
}
2312+
else if(can_cast_type<unsignedbv_typet>(op0.type()))
2313+
{
2314+
// Set the type width
2315+
type_width = to_unsignedbv_type(op0.type()).get_width();
2316+
}
2317+
else
2318+
{
2319+
// Type that can't be represented as bitvector
2320+
// get some kind of width in a potentially unsafe way
2321+
type_width = op0.type().get_size_t("width");
2322+
}
2323+
// Construct the "width(AAAA)" constant
2324+
const exprt width_expr =
2325+
from_integer(type_width, rotate_expr.distance().type());
2326+
// Apply modulo to n since shifting will overflow
2327+
// That is: 0001 << 4 == 0, but 0001 rol 4 == 0001
2328+
const exprt distance_modulo_width =
2329+
mod_exprt(rotate_expr.distance(), width_expr);
2330+
// Now put the pieces together
2331+
// width(AAAA) - (n % width(AAAA))
2332+
const auto complement_width_expr =
2333+
minus_exprt(width_expr, distance_modulo_width);
2334+
// lhs and rhs components defined according to rol/ror
2335+
exprt lhs_expr;
2336+
exprt rhs_expr;
2337+
if(src.id() == ID_rol)
2338+
{
2339+
// AAAA << (n % width(AAAA))
2340+
lhs_expr = shl_exprt(op0, distance_modulo_width);
2341+
// AAAA >> complement_width_expr
2342+
rhs_expr = ashr_exprt(op0, complement_width_expr);
2343+
}
2344+
else if(src.id() == ID_ror)
2345+
{
2346+
// AAAA >> (n % width(AAAA))
2347+
lhs_expr = ashr_exprt(op0, distance_modulo_width);
2348+
// AAAA << complement_width_expr
2349+
rhs_expr = shl_exprt(op0, complement_width_expr);
2350+
}
2351+
else
2352+
{
2353+
// Someone called this function when they shouldn't have.
2354+
UNREACHABLE;
2355+
}
2356+
return convert_with_precedence(bitor_exprt(lhs_expr, rhs_expr), precedence);
2357+
}
2358+
22932359
std::string expr2ct::convert_designated_initializer(const exprt &src)
22942360
{
22952361
if(src.operands().size()!=1)
@@ -3794,6 +3860,9 @@ std::string expr2ct::convert_with_precedence(
37943860
else if(src.id()==ID_type)
37953861
return convert(src.type());
37963862

3863+
else if(src.id() == ID_rol || src.id() == ID_ror)
3864+
return convert_rox(src, precedence);
3865+
37973866
auto function_string_opt = convert_function(src);
37983867
if(function_string_opt.has_value())
37993868
return *function_string_opt;

branches/variant-submodule/src/ansi-c/expr2c_class.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,15 @@ class expr2ct
126126
const std::string &symbol2,
127127
unsigned precedence);
128128

129+
/// Conversion function from rol/ror expressions to C code strings
130+
/// Note that this constructs a complex expression to do bit
131+
/// twiddling since rol/ror operations are not native to ANSI-C.
132+
/// The complex expression is then recursively converted.
133+
/// \param src: is an exprt that must be either an rol or ror
134+
/// \param precedence: precedence for bracketing
135+
/// \returns string for performing rol/ror as bit twiddling with C
136+
std::string convert_rox(const exprt &src, unsigned precedence);
137+
129138
std::string convert_overflow(
130139
const exprt &src, unsigned &precedence);
131140

0 commit comments

Comments
 (0)