Skip to content

Commit d7dbf7e

Browse files
committed
Handle floating point operators with non-default rms
1 parent be62647 commit d7dbf7e

File tree

4 files changed

+84
-46
lines changed

4 files changed

+84
-46
lines changed

src/smtml/expr.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ let rec ty (hte : t) : Ty.t =
109109
| Ptr _ -> Ty_bitv 32
110110
| Symbol x -> Symbol.type_of x
111111
| List _ -> Ty_list
112-
| App _ -> Ty_app
112+
| App (sym, _) -> begin match sym.ty with Ty_none -> Ty_app | ty -> ty end
113113
| Unop (ty, _, _) -> ty
114114
| Binop (ty, _, _, _) -> ty
115115
| Triop (_, Ite, _, hte1, hte2) ->

src/smtml/mappings.ml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,20 @@ module Make (M_with_make : M_with_make) : S_with_fresh = struct
656656
| Ty.Ty_regexp -> Regexp_impl.naryop
657657
| ty -> Fmt.failwith "Naryop for type \"%a\" not implemented" Ty.pp ty
658658

659+
let get_rounding_mode rm =
660+
match Expr.view rm with
661+
| Symbol { name = Simple ("roundNearestTiesToEven" | "RNE"); _ } ->
662+
M.Float.Rounding_mode.rne
663+
| Symbol { name = Simple ("roundNearestTiesToAway" | "RNA"); _ } ->
664+
M.Float.Rounding_mode.rna
665+
| Symbol { name = Simple ("roundTowardPositive" | "RTP"); _ } ->
666+
M.Float.Rounding_mode.rtp
667+
| Symbol { name = Simple ("roundTowardNegative" | "RTN"); _ } ->
668+
M.Float.Rounding_mode.rtn
669+
| Symbol { name = Simple ("roundTowardZero" | "RTZ"); _ } ->
670+
M.Float.Rounding_mode.rtz
671+
| _ -> Fmt.failwith "unknown rouding mode: %a" Expr.pp rm
672+
659673
let rec encode_expr ctx (hte : Expr.t) : symbol_ctx * M.term =
660674
match Expr.view hte with
661675
| Val value -> (ctx, v value)
@@ -664,6 +678,35 @@ module Make (M_with_make : M_with_make) : S_with_fresh = struct
664678
let ctx, offset' = encode_expr ctx offset in
665679
(ctx, I32.binop Add base' offset')
666680
| Symbol sym -> make_symbol ctx sym
681+
(* FIXME: add a way to support building these expressions without apps *)
682+
| App ({ name = Simple "fp.add"; _ }, [ rm; a; b ]) ->
683+
let ctx, a = encode_expr ctx a in
684+
let ctx, b = encode_expr ctx b in
685+
let rm = get_rounding_mode rm in
686+
(ctx, M.Float.add ~rm a b)
687+
| App ({ name = Simple "fp.sub"; _ }, [ rm; a; b ]) ->
688+
let ctx, a = encode_expr ctx a in
689+
let ctx, b = encode_expr ctx b in
690+
let rm = get_rounding_mode rm in
691+
(ctx, M.Float.sub ~rm a b)
692+
| App ({ name = Simple "fp.mul"; _ }, [ rm; a; b ]) ->
693+
let ctx, a = encode_expr ctx a in
694+
let ctx, b = encode_expr ctx b in
695+
let rm = get_rounding_mode rm in
696+
(ctx, M.Float.mul ~rm a b)
697+
| App ({ name = Simple "fp.div"; _ }, [ rm; a; b ]) ->
698+
let ctx, a = encode_expr ctx a in
699+
let ctx, b = encode_expr ctx b in
700+
let rm = get_rounding_mode rm in
701+
(ctx, M.Float.div ~rm a b)
702+
| App ({ name = Simple "fp.sqrt"; _ }, [ rm; a ]) ->
703+
let ctx, a = encode_expr ctx a in
704+
let rm = get_rounding_mode rm in
705+
(ctx, M.Float.sqrt ~rm a)
706+
| App ({ name = Simple "fp.roundToIntegral"; _ }, [ rm; a ]) ->
707+
let ctx, a = encode_expr ctx a in
708+
let rm = get_rounding_mode rm in
709+
(ctx, M.Float.round_to_integral ~rm a)
667710
| App (sym, args) ->
668711
let name =
669712
match Symbol.name sym with

src/smtml/rewrite.ml

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,28 @@ let rec rewrite_expr (type_map, expr_map) hte =
3838
| Val _ -> hte
3939
| Ptr { base; offset } ->
4040
Expr.ptr base (rewrite_expr (type_map, expr_map) offset)
41-
| Symbol sym -> (
41+
| Symbol sym -> begin
4242
match Symb_map.find_opt sym type_map with
4343
| None -> (
4444
match Symb_map.find_opt sym expr_map with
4545
| None -> Fmt.failwith "Undefined symbol: %a" Symbol.pp sym
4646
| Some expr -> expr )
47-
| Some ty -> Expr.symbol { sym with ty } )
47+
| Some ty -> Expr.symbol { sym with ty }
48+
end
4849
| List htes -> Expr.list (List.map (rewrite_expr (type_map, expr_map)) htes)
50+
| App
51+
( ({ name = Simple ("fp.add" | "fp.sub" | "fp.mul" | "fp.div"); _ } as sym)
52+
, [ rm; a; b ] ) ->
53+
let a = rewrite_expr (type_map, expr_map) a in
54+
let b = rewrite_expr (type_map, expr_map) b in
55+
let ty = rewrite_ty Ty_none [ Expr.ty a; Expr.ty b ] in
56+
Expr.app { sym with ty } [ rm; a; b ]
57+
| App
58+
( ({ name = Simple ("fp.sqrt" | "fp.roundToIntegral"); _ } as sym)
59+
, [ rm; a ] ) ->
60+
let a = rewrite_expr (type_map, expr_map) a in
61+
let ty = rewrite_ty Ty_none [ Expr.ty a ] in
62+
Expr.app { sym with ty } [ rm; a ]
4963
| App (sym, htes) ->
5064
let sym =
5165
match Symb_map.find_opt sym type_map with

src/smtml/smtlib.ml

Lines changed: 24 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,12 @@ module Term = struct
135135
let exponent_shifted = Int32.shift_left exponent 23 in
136136
Int32.logor sign_shifted (Int32.logor exponent_shifted mantissa)
137137

138+
let make_fp_binop symbol (op : Ty.Binop.t) rm a b =
139+
match Expr.view rm with
140+
| Symbol { name = Simple "roundNearestTiesToEven"; _ } ->
141+
Expr.raw_binop Ty_none op a b
142+
| _ -> Expr.app symbol [ rm; a; b ]
143+
138144
let apply ?loc (id : t) (args : t list) : t =
139145
match Expr.view id with
140146
| Symbol ({ namespace = Term; name = Simple name; _ } as symbol) -> (
@@ -237,63 +243,38 @@ module Term = struct
237243
Expr.pp eb Expr.pp i )
238244
| "fp.abs", [ a ] -> Expr.raw_unop Ty_none Abs a
239245
| "fp.neg", [ a ] -> Expr.raw_unop Ty_none Neg a
240-
| ( "fp.add"
241-
, [ { node = Symbol { name = Simple "roundNearestTiesToEven"; _ }; _ }
242-
; a
243-
; b
244-
] ) ->
245-
Expr.raw_binop Ty_none Add a b
246-
| ( "fp.sub"
247-
, [ { node = Symbol { name = Simple "roundNearestTiesToEven"; _ }; _ }
248-
; a
249-
; b
250-
] ) ->
251-
Expr.raw_binop Ty_none Sub a b
252-
| ( "fp.mul"
253-
, [ { node = Symbol { name = Simple "roundNearestTiesToEven"; _ }; _ }
254-
; a
255-
; b
256-
] ) ->
257-
Expr.raw_binop Ty_none Mul a b
258-
| ( "fp.div"
259-
, [ { node = Symbol { name = Simple "roundNearestTiesToEven"; _ }; _ }
260-
; a
261-
; b
262-
] ) ->
263-
Expr.raw_binop Ty_none Div a b
246+
| "fp.add", [ rm; a; b ] -> make_fp_binop symbol Add rm a b
247+
| "fp.sub", [ rm; a; b ] -> make_fp_binop symbol Sub rm a b
248+
| "fp.mul", [ rm; a; b ] -> make_fp_binop symbol Mul rm a b
249+
| "fp.div", [ rm; a; b ] -> make_fp_binop symbol Div rm a b
264250
| ( "fp.sqrt"
265251
, [ { node = Symbol { name = Simple "roundNearestTiesToEven"; _ }; _ }
266252
; a
267253
] ) ->
268254
Expr.raw_unop Ty_none Sqrt a
269255
| "fp.rem", [ a; b ] -> Expr.raw_binop Ty_none Rem a b
270-
| ( "fp.roundToIntegral"
271-
, [ { node = Symbol { name = Simple "roundNearestTiesToEven"; _ }; _ }
272-
; a
273-
] ) ->
274-
Expr.raw_unop Ty_none Nearest a
275-
| ( "fp.roundToIntegral"
276-
, [ { node = Symbol { name = Simple "roundTowardPositive"; _ }; _ }; a ]
277-
) ->
278-
Expr.raw_unop Ty_none Ceil a
279-
| ( "fp.roundToIntegral"
280-
, [ { node = Symbol { name = Simple "roundTowardNegative"; _ }; _ }; a ]
281-
) ->
282-
Expr.raw_unop Ty_none Floor a
283-
| ( "fp.roundToIntegral"
284-
, [ { node = Symbol { name = Simple "roundTowardZero"; _ }; _ }; a ] )
285-
->
286-
Expr.raw_unop Ty_none Trunc a
256+
| "fp.roundToIntegral", [ rm; a ] -> begin
257+
match Expr.view rm with
258+
| Symbol { name = Simple "roundNearestTiesToEven"; _ } ->
259+
Expr.raw_unop Ty_none Nearest a
260+
| Symbol { name = Simple "roundTowardPositive"; _ } ->
261+
Expr.raw_unop Ty_none Ceil a
262+
| Symbol { name = Simple "roundTowardNegative"; _ } ->
263+
Expr.raw_unop Ty_none Floor a
264+
| Symbol { name = Simple "roundTowardZero"; _ } ->
265+
Expr.raw_unop Ty_none Trunc a
266+
| _ -> Expr.app symbol args
267+
end
287268
| "fp.min", [ a; b ] -> Expr.raw_binop Ty_none Min a b
288269
| "fp.max", [ a; b ] -> Expr.raw_binop Ty_none Max a b
289270
| "fp.leq", [ a; b ] -> Expr.raw_relop Ty_none Le a b
290271
| "fp.lt", [ a; b ] -> Expr.raw_relop Ty_none Lt a b
291272
| "fp.geq", [ a; b ] -> Expr.raw_relop Ty_none Ge a b
292273
| "fp.gt", [ a; b ] -> Expr.raw_relop Ty_none Gt a b
293274
| "fp.eq", [ a; b ] -> Expr.raw_relop Ty_none Eq a b
294-
| _, l ->
275+
| _ ->
295276
Log.debug (fun k -> k "apply: unknown %a making app" Symbol.pp symbol);
296-
Expr.app symbol l )
277+
Expr.app symbol args )
297278
| Symbol ({ name = Simple _; namespace = Attr; _ } as attr) ->
298279
Log.debug (fun k -> k "apply: unknown %a making app" Symbol.pp attr);
299280
Expr.app attr args

0 commit comments

Comments
 (0)