runTimes->stop(RunTimes::Transforming);
- return result;
+ return result;
}
//Translates signed BVDIV,BVMOD and BVREM into unsigned variety
}
// This is the modulus of dividing rounding to -infinity.
- // Except if the signs are different, and it perfectly divides
- // the modulus is the divisor (not zero).
else if (SBVMOD == in.GetKind())
{
- // (let (?msb_s (extract[|m-1|:|m-1|] s))
- // (let (?msb_t (extract[|m-1|:|m-1|] t))
- // (ite (and (= ?msb_s bit0) (= ?msb_t bit0))
- // (bvurem s t)
- // (ite (and (= ?msb_s bit1) (= ?msb_t bit0))
- // (bvadd (bvneg (bvurem (bvneg s) t)) t)
- // (ite (and (= ?msb_s bit0) (= ?msb_t bit1))
- // (bvadd (bvurem s (bvneg t)) t)
- // (bvneg (bvurem (bvneg s) (bvneg t)))))))
+
+ /*
+ (bvsmod s t) abbreviates
+ (let ((?msb_s ((_ extract |m-1| |m-1|) s))
+ (?msb_t ((_ extract |m-1| |m-1|) t)))
+ (let ((abs_s (ite (= ?msb_s #b0) s (bvneg s)))
+ (abs_t (ite (= ?msb_t #b0) t (bvneg t))))
+ (let ((u (bvurem abs_s abs_t)))
+ (ite (= u (_ bv0 m))
+ u
+ (ite (and (= ?msb_s #b0) (= ?msb_t #b0))
+ u
+ (ite (and (= ?msb_s #b1) (= ?msb_t #b0))
+ (bvadd (bvneg u) t)
+ (ite (and (= ?msb_s #b0) (= ?msb_t #b1))
+ (bvadd u t)
+ (bvneg u))))))))
+ */
//Take absolute value.
ASTNode pos_dividend =
nf->CreateTerm(BVUMINUS, len, urem_node),
urem_node);
- // if It's XOR <0 then add t (not its absolute value).
+ // if It's XOR <0, and it doesn't perfectly divide, then add t (not its absolute value).
ASTNode xor_node =
nf->CreateNode(XOR, cond_dividend, cond_divisor);
+ ASTNode neZ = nf->CreateNode(NOT, nf->CreateNode(EQ, rev_node, bm->CreateZeroConst(divisor.GetValueWidth())));
+ ASTNode cond = nf->CreateNode(AND,xor_node ,neZ);
ASTNode n =
nf->CreateTerm(ITE, len,
- xor_node,
+ cond,
nf->CreateTerm(BVPLUS, len, rev_node, divisor),
rev_node);
case SBVMOD:
{
assert(2==number_of_children);
- /* Definition taken from the SMTLIB website
- (bvsmod s t) abbreviates
- (let (?msb_s (extract[|m-1|:|m-1|] s))
- (let (?msb_t (extract[|m-1|:|m-1|] t))
- (ite (and (= ?msb_s bit0) (= ?msb_t bit0))
- (bvurem s t)
- (ite (and (= ?msb_s bit1) (= ?msb_t bit0))
- (bvadd (bvneg (bvurem (bvneg s) t)) t)
- (ite (and (= ?msb_s bit0) (= ?msb_t bit1))
- (bvadd (bvurem s (bvneg t)) t)
- (bvneg (bvurem (bvneg s) (bvneg t)))))))
- */
+/*
+ (bvsmod s t) abbreviates
+ (let ((?msb_s ((_ extract |m-1| |m-1|) s))
+ (?msb_t ((_ extract |m-1| |m-1|) t)))
+ (let ((abs_s (ite (= ?msb_s #b0) s (bvneg s)))
+ (abs_t (ite (= ?msb_t #b0) t (bvneg t))))
+ (let ((u (bvurem abs_s abs_t)))
+ (ite (= u (_ bv0 m))
+ u
+ (ite (and (= ?msb_s #b0) (= ?msb_t #b0))
+ u
+ (ite (and (= ?msb_s #b1) (= ?msb_t #b0))
+ (bvadd (bvneg u) t)
+ (ite (and (= ?msb_s #b0) (= ?msb_t #b1))
+ (bvadd u t)
+ (bvneg u))))))))
+*/
assert(input_children[0].GetValueWidth() == input_children[1].GetValueWidth());
CONSTANTBV::BitVector_Negate(tmp0b, tmp0);
CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Div_Pos(quotient, tmp0b, tmp1, remainder);
-
assert(e == CONSTANTBV::ErrCode_Ok);
CBV remb = CONSTANTBV::BitVector_Create(inputwidth, true);
CONSTANTBV::BitVector_Negate(remb, remainder);
- bool carry = false;
- CBV res = CONSTANTBV::BitVector_Create(inputwidth, true);
- CONSTANTBV::BitVector_add(res, remb, tmp1, &carry);
-
- OutputNode = _bm->CreateBVConst(res, outputwidth);
+ if (CONSTANTBV::BitVector_is_empty(remb))
+ {
+ OutputNode = _bm->CreateZeroConst(outputwidth);
+ }
+ else
+ {
+ CBV res = CONSTANTBV::BitVector_Create(inputwidth, true);
+ bool carry = false;
+ CONSTANTBV::BitVector_add(res, remb, tmp1, &carry);
+ OutputNode = _bm->CreateBVConst(res, outputwidth);
+ }
- CONSTANTBV::BitVector_Destroy(tmp0b);
CONSTANTBV::BitVector_Destroy(remb);
+ CONSTANTBV::BitVector_Destroy(tmp0b);
CONSTANTBV::BitVector_Destroy(remainder);
}
else if (!isNegativeS && isNegativeT)
assert(e == CONSTANTBV::ErrCode_Ok);
- bool carry = false;
- CBV res = CONSTANTBV::BitVector_Create(inputwidth, true);
- CONSTANTBV::BitVector_add(res, remainder, tmp1, &carry);
-
- OutputNode = _bm->CreateBVConst(res, outputwidth);
+ if (CONSTANTBV::BitVector_is_empty(remainder))
+ {
+ OutputNode = _bm->CreateZeroConst(outputwidth);
+ }
+ else
+ {
+ CBV res = CONSTANTBV::BitVector_Create(inputwidth, true);
+ bool carry = false;
+ CONSTANTBV::BitVector_add(res, remainder, tmp1, &carry);
+ OutputNode = _bm->CreateBVConst(res, outputwidth);
+ }
CONSTANTBV::BitVector_Destroy(tmp1b);
CONSTANTBV::BitVector_Destroy(remainder);