Skip to content

Commit 3a26e73

Browse files
authored
Merge pull request #7333 from diffblue/smt2_to_fp_unsigned
SMT2 parser: implement to_fp_unsigned
2 parents df8ae3b + 5cc1648 commit 3a26e73

File tree

6 files changed

+80
-5
lines changed

6 files changed

+80
-5
lines changed

regression/cbmc/Float-no-simp2/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE broken-cprover-smt-backend
1+
CORE
22
main.c
33
--floatbv --no-simplify
44
^EXIT=0$

regression/cbmc/Float-to-int1/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE broken-smt-backend
1+
CORE broken-z3-smt-backend
22
main.c
33
--floatbv
44
^EXIT=0$

regression/cbmc/Float-to-int2/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE broken-smt-backend
1+
CORE
22
main.c
33
--floatbv
44
^EXIT=0$

regression/cbmc/Float-to-int3/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE broken-smt-backend
1+
CORE broken-z3-smt-backend
22
main.c
33
--floatbv
44
^EXIT=0$

regression/cbmc/Float12/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE broken-cprover-smt-backend
1+
CORE
22
main.c
33

44
^EXIT=0$

src/solvers/smt2/smt2_parser.cpp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,69 @@ exprt smt2_parsert::function_application()
800800
else
801801
throw error() << "unexpected sort given as operand to to_fp";
802802
}
803+
else if(id == "to_fp_unsigned")
804+
{
805+
if(next_token() != smt2_tokenizert::NUMERAL)
806+
throw error("expected number after to_fp_unsigned");
807+
808+
auto width_e = std::stoll(smt2_tokenizer.get_buffer());
809+
810+
if(next_token() != smt2_tokenizert::NUMERAL)
811+
throw error("expected second number after to_fp_unsigned");
812+
813+
auto width_f = std::stoll(smt2_tokenizer.get_buffer());
814+
815+
if(next_token() != smt2_tokenizert::CLOSE)
816+
throw error("expected ')' after to_fp_unsigned");
817+
818+
// width_f *includes* the hidden bit
819+
const ieee_float_spect spec(width_f - 1, width_e);
820+
821+
auto rounding_mode = expression();
822+
823+
auto source_op = expression();
824+
825+
if(next_token() != smt2_tokenizert::CLOSE)
826+
throw error("expected ')' at the end of to_fp_unsigned");
827+
828+
if(source_op.type().id() == ID_unsignedbv)
829+
{
830+
// The operand is hard-wired to be interpreted
831+
// as an unsigned number.
832+
return floatbv_typecast_exprt(
833+
source_op, rounding_mode, spec.to_type());
834+
}
835+
else
836+
throw error()
837+
<< "unexpected sort given as operand to to_fp_unsigned";
838+
}
839+
else if(id == "fp.to_sbv" || id == "fp.to_ubv")
840+
{
841+
// These are indexed by the number of bits of the result.
842+
if(next_token() != smt2_tokenizert::NUMERAL)
843+
throw error() << "expected number after " << id;
844+
845+
auto width = std::stoll(smt2_tokenizer.get_buffer());
846+
847+
if(next_token() != smt2_tokenizert::CLOSE)
848+
throw error() << "expected ')' after " << id;
849+
850+
auto op = operands();
851+
852+
if(op.size() != 2)
853+
throw error() << id << " takes two operands";
854+
855+
if(op[1].type().id() != ID_floatbv)
856+
throw error() << id << " takes a FloatingPoint operand";
857+
858+
if(id == "fp.to_sbv")
859+
return typecast_exprt(
860+
floatbv_typecast_exprt(op[1], op[0], signedbv_typet(width)),
861+
unsignedbv_typet(width));
862+
else
863+
return floatbv_typecast_exprt(
864+
op[1], op[0], unsignedbv_typet(width));
865+
}
803866
else
804867
{
805868
throw error() << "unknown indexed identifier '"
@@ -1269,6 +1332,18 @@ void smt2_parsert::setup_expressions()
12691332
return isnormal_exprt(op[0]);
12701333
};
12711334

1335+
expressions["fp.isZero"] = [this] {
1336+
auto op = operands();
1337+
1338+
if(op.size() != 1)
1339+
throw error("fp.isZero takes one operand");
1340+
1341+
if(op[0].type().id() != ID_floatbv)
1342+
throw error("fp.isZero takes FloatingPoint operand");
1343+
1344+
return not_exprt(typecast_exprt(op[0], bool_typet()));
1345+
};
1346+
12721347
expressions["fp"] = [this] { return function_application_fp(operands()); };
12731348

12741349
expressions["fp.add"] = [this] {

0 commit comments

Comments
 (0)