@@ -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