Skip to content

Commit f1dee7c

Browse files
committed
btorsim: implement smod
smod is defined as the remainder of a signed division, but with the sign of the divisor. Delegate to srem and adjust the sign afterward to avoid duplicating the division logic. Signed-off-by: Ferdinand Bachmann <[email protected]>
1 parent 37e4beb commit f1dee7c

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

src/btorsim/btorsim.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ parse_model_line (Btor2Line *l)
267267
case BTOR2_TAG_sll:
268268
case BTOR2_TAG_slt:
269269
case BTOR2_TAG_slte:
270+
case BTOR2_TAG_smod:
270271
case BTOR2_TAG_sra:
271272
case BTOR2_TAG_srem:
272273
case BTOR2_TAG_srl:
@@ -288,7 +289,6 @@ parse_model_line (Btor2Line *l)
288289
case BTOR2_TAG_justice:
289290
case BTOR2_TAG_saddo:
290291
case BTOR2_TAG_sdivo:
291-
case BTOR2_TAG_smod:
292292
case BTOR2_TAG_smulo:
293293
case BTOR2_TAG_ssubo:
294294
case BTOR2_TAG_uaddo:
@@ -624,6 +624,12 @@ simulate (int64_t id)
624624
assert (args[1].type == BtorSimState::Type::BITVEC);
625625
res.bv_state = btorsim_bv_sll (args[0].bv_state, args[1].bv_state);
626626
break;
627+
case BTOR2_TAG_smod:
628+
assert (l->nargs == 2);
629+
assert (res.type == BtorSimState::Type::BITVEC);
630+
assert (args[0].type == BtorSimState::Type::BITVEC);
631+
assert (args[1].type == BtorSimState::Type::BITVEC);
632+
res.bv_state = btorsim_bv_smod (args[0].bv_state, args[1].bv_state);
627633
case BTOR2_TAG_srl:
628634
assert (l->nargs == 2);
629635
assert (res.type == BtorSimState::Type::BITVEC);

src/btorsim/btorsimbv.c

+23
Original file line numberDiff line numberDiff line change
@@ -2033,6 +2033,29 @@ btorsim_bv_srem (const BtorSimBitVector *a, const BtorSimBitVector *b)
20332033
return res;
20342034
}
20352035

2036+
BtorSimBitVector *
2037+
btorsim_bv_smod (const BtorSimBitVector *a, const BtorSimBitVector *b)
2038+
{
2039+
BtorSimBitVector *srem, *sign_srem, *srem_abs, *sign_b, *res;
2040+
2041+
// take absolute value of srem
2042+
srem = btorsim_bv_srem(a, b);
2043+
sign_srem = btorsim_bv_slice(srem, srem->width - 1, srem->width - 1);
2044+
srem_abs = btorsim_bv_is_true(sign_srem) ? btorsim_bv_neg(srem)
2045+
: btorsim_bv_copy(srem);
2046+
2047+
// apply sign of divisor
2048+
sign_b = btorsim_bv_slice (b, b->width - 1, b->width - 1);
2049+
res = btorsim_bv_is_true(sign_b) ? btorsim_bv_neg(srem_abs) :
2050+
btorsim_bv_copy(srem_abs);
2051+
2052+
btorsim_bv_free(srem);
2053+
btorsim_bv_free(sign_srem);
2054+
btorsim_bv_free(srem_abs);
2055+
btorsim_bv_free(sign_b);
2056+
return res;
2057+
}
2058+
20362059
BtorSimBitVector *
20372060
btorsim_bv_concat (const BtorSimBitVector *a, const BtorSimBitVector *b)
20382061
{

src/btorsim/btorsimbv.h

+3
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,9 @@ BtorSimBitVector *btorsim_bv_urem (const BtorSimBitVector *a,
212212
BtorSimBitVector *btorsim_bv_srem (const BtorSimBitVector *a,
213213
const BtorSimBitVector *b);
214214

215+
BtorSimBitVector *btorsim_bv_smod (const BtorSimBitVector *a,
216+
const BtorSimBitVector *b);
217+
215218
BtorSimBitVector *btorsim_bv_ite (const BtorSimBitVector *c,
216219
const BtorSimBitVector *t,
217220
const BtorSimBitVector *e);

0 commit comments

Comments
 (0)