Skip to content

Commit

Permalink
Support of and and srl
Browse files Browse the repository at this point in the history
  • Loading branch information
ckirsch committed Feb 21, 2024
1 parent b042d4a commit b1b9781
Showing 1 changed file with 113 additions and 14 deletions.
127 changes: 113 additions & 14 deletions tools/rotor.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,11 @@ void write_value(uint64_t* array_nid, uint64_t index, uint64_t value);
uint64_t is_n_times_n_to_n_operator(char* op);
uint64_t is_n_times_n_operator(char* op);

uint64_t bitwise(uint64_t a, uint64_t b, uint64_t and_xor, uint64_t or_xor);
uint64_t bitwise_and(uint64_t a, uint64_t b);
uint64_t bitwise_or(uint64_t a, uint64_t b);
uint64_t bitwise_xor(uint64_t a, uint64_t b);

uint64_t get_cached_state(uint64_t* line);

uint64_t eval_constant_value(uint64_t* line);
Expand Down Expand Up @@ -3077,7 +3082,23 @@ void write_value(uint64_t* array_nid, uint64_t index, uint64_t value) {
exit(EXITCODE_SYSTEMERROR);
}

uint64_t is_n_times_n_to_n_operator(char* op) {
uint64_t is_comparison_operator(char* op) {
if (op == OP_ULTE)
return 1;
else
return 0;
}

uint64_t is_bitwise_operator(char* op) {
if (op == OP_AND)
return 1;
else if (op == OP_SRL)
return 1;
else
return 0;
}

uint64_t is_arithmetic_operator(char* op) {
if (op == OP_ADD)
return 1;
else if (op == OP_SUB)
Expand All @@ -3086,13 +3107,77 @@ uint64_t is_n_times_n_to_n_operator(char* op) {
return 0;
}

uint64_t is_n_times_n_to_n_operator(char* op) {
if (is_bitwise_operator(op))
return 1;
else if (is_arithmetic_operator(op))
return 1;
else
return 0;
}

uint64_t is_n_times_n_operator(char* op) {
if (op == OP_ULTE)
if (is_comparison_operator(op))
return 1;
else
return is_n_times_n_to_n_operator(op);
}

uint64_t bitwise(uint64_t a, uint64_t b, uint64_t and_xor, uint64_t or_xor) {
uint64_t r;
uint64_t i;

if (a == b)
return a;
else if (a < b)
r = b;
else {
r = a;

a = b;
b = r;
}

// assert: a < b and r == b

i = 0;

while (i < SIZEOFUINT64INBITS) {
if (a == 0) {
if (or_xor)
return r;
else
return r % two_to_the_power_of(i);
}

if (a % 2 == or_xor) {
if (b % 2)
r = r - and_xor * two_to_the_power_of(i);
else
r = r + or_xor * two_to_the_power_of(i);
}

a = a / 2;
b = b / 2;

i = i + 1;
}

return r;
}

uint64_t bitwise_and(uint64_t a, uint64_t b) {
return bitwise(a, b, 1, 0);
}

uint64_t bitwise_or(uint64_t a, uint64_t b) {
return bitwise(a, b, 0, 1);
}

uint64_t bitwise_xor(uint64_t a, uint64_t b) {
return bitwise(a, b, 1, 1);
}

uint64_t get_cached_state(uint64_t* line) {
if (get_op(line) == OP_STATE)
if ((char*) get_arg1(get_sid(line)) == ARRAY)
Expand Down Expand Up @@ -3337,22 +3422,36 @@ uint64_t eval_binary_op(uint64_t* line) {
if (is_n_times_n_operator(op)) {
match_sorts(get_sid(left_nid), get_sid(right_nid), "left and right operand");

size = eval_bitvec_size(get_sid(left_nid));
left_value = eval_line(left_nid);
right_value = eval_line(right_nid);

if (is_bitwise_operator(op)) {
match_sorts(get_sid(line), get_sid(left_nid), "bitwise operator");

if (op == OP_AND)
set_state(line, bitwise_and(left_value, right_value));
else if (op == OP_SRL)
set_state(line, right_shift(left_value, right_value));
} else {
size = eval_bitvec_size(get_sid(left_nid));

left_value = sign_extend(eval_line(left_nid), size);
right_value = sign_extend(eval_line(right_nid), size);
left_value = sign_extend(left_value, size);
right_value = sign_extend(right_value, size);

if (is_n_times_n_to_n_operator(op)) {
match_sorts(get_sid(line), get_sid(left_nid), "operator");
if (is_arithmetic_operator(op)) {
match_sorts(get_sid(line), get_sid(left_nid), "arithmetic operator");

if (op == OP_ADD)
set_state(line, sign_shrink(left_value + right_value, size));
else if (op == OP_SUB)
set_state(line, sign_shrink(left_value - right_value, size));
} else if (op == OP_ULTE) {
match_sorts(get_sid(line), SID_BOOLEAN, "Boolean operator");
if (op == OP_ADD)
set_state(line, sign_shrink(left_value + right_value, size));
else if (op == OP_SUB)
set_state(line, sign_shrink(left_value - right_value, size));
} else if (is_comparison_operator(op)) {
if (op == OP_ULTE) {
match_sorts(get_sid(line), SID_BOOLEAN, "comparison operator");

set_state(line, left_value <= right_value);
set_state(line, left_value <= right_value);
}
}
}

set_step(line, current_step);
Expand Down

0 comments on commit b1b9781

Please sign in to comment.