1
|
(********************************************************************)
|
2
|
(* *)
|
3
|
(* The LustreC compiler toolset / The LustreC Development Team *)
|
4
|
(* Copyright 2012 - -- ONERA - CNRS - INPT *)
|
5
|
(* *)
|
6
|
(* LustreC is free software, distributed WITHOUT ANY WARRANTY *)
|
7
|
(* under the terms of the GNU Lesser General Public License *)
|
8
|
(* version 2.1. *)
|
9
|
(* *)
|
10
|
(********************************************************************)
|
11
|
|
12
|
open Utils.Format
|
13
|
open Lustre_types
|
14
|
open Machine_code_types
|
15
|
open C_backend_common
|
16
|
open Machine_code_common
|
17
|
open Corelang
|
18
|
|
19
|
(**************************************************************************)
|
20
|
(* Printing spec for c *)
|
21
|
|
22
|
(**************************************************************************)
|
23
|
(* OLD STUFF ???
|
24
|
|
25
|
|
26
|
let pp_acsl_type var fmt t =
|
27
|
let rec aux t pp_suffix =
|
28
|
match (Types.repr t).Types.tdesc with
|
29
|
| Types.Tclock t' -> aux t' pp_suffix
|
30
|
| Types.Tbool -> fprintf fmt "int %s%a" var pp_suffix ()
|
31
|
| Types.Treal -> fprintf fmt "real %s%a" var pp_suffix ()
|
32
|
| Types.Tint -> fprintf fmt "int %s%a" var pp_suffix ()
|
33
|
| Types.Tarray (d, t') ->
|
34
|
let pp_suffix' fmt () = fprintf fmt "%a[%a]" pp_suffix () pp_c_dimension d in
|
35
|
aux t' pp_suffix'
|
36
|
(* | Types.Tstatic (_, t') -> fprintf fmt "const "; aux t' pp_suffix *)
|
37
|
(* | Types.Tconst ty -> fprintf fmt "%s %s" ty var *)
|
38
|
(* | Types.Tarrow (_, _) -> fprintf fmt "void (\*%s)()" var *)
|
39
|
| _ -> eprintf "internal error: pp_acsl_type %a@." Types.print_ty t; assert false
|
40
|
in aux t (fun fmt () -> ())
|
41
|
|
42
|
let pp_acsl_var_decl fmt id =
|
43
|
pp_acsl_type id.var_id fmt id.var_type
|
44
|
|
45
|
|
46
|
let rec pp_eexpr is_output fmt eexpr =
|
47
|
let pp_eexpr = pp_eexpr is_output in
|
48
|
match eexpr.eexpr_desc with
|
49
|
| EExpr_const c -> Printers.pp_econst fmt c
|
50
|
| EExpr_ident id ->
|
51
|
if is_output id then pp_print_string fmt ("*" ^ id) else pp_print_string fmt id
|
52
|
| EExpr_tuple el -> Utils.fprintf_list ~sep:"," pp_eexpr fmt el
|
53
|
| EExpr_arrow (e1, e2) -> fprintf fmt "%a -> %a" pp_eexpr e1 pp_eexpr e2
|
54
|
| EExpr_fby (e1, e2) -> fprintf fmt "%a fby %a" pp_eexpr e1 pp_eexpr e2
|
55
|
(* | EExpr_concat (e1, e2) -> fprintf fmt "%a::%a" pp_eexpr e1 pp_eexpr e2 *)
|
56
|
(* | EExpr_tail e -> fprintf fmt "tail %a" pp_eexpr e *)
|
57
|
| EExpr_pre e -> fprintf fmt "pre %a" pp_eexpr e
|
58
|
| EExpr_when (e, id) -> fprintf fmt "%a when %s" pp_eexpr e id
|
59
|
| EExpr_merge (id, e1, e2) ->
|
60
|
fprintf fmt "merge (%s, %a, %a)" id pp_eexpr e1 pp_eexpr e2
|
61
|
| EExpr_appl (id, e, r) -> pp_eapp is_output fmt id e r
|
62
|
| EExpr_forall (vars, e) -> fprintf fmt "forall %a; %a" Printers.pp_node_args vars pp_eexpr e
|
63
|
| EExpr_exists (vars, e) -> fprintf fmt "exists %a; %a" Printers.pp_node_args vars pp_eexpr e
|
64
|
|
65
|
|
66
|
(* | EExpr_whennot _ *)
|
67
|
(* | EExpr_uclock _ *)
|
68
|
(* | EExpr_dclock _ *)
|
69
|
(* | EExpr_phclock _ -> assert false *)
|
70
|
and pp_eapp is_output fmt id e r =
|
71
|
let pp_eexpr = pp_eexpr is_output in
|
72
|
match r with
|
73
|
| None ->
|
74
|
(match id, e.eexpr_desc with
|
75
|
| "+", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a + %a)" pp_eexpr e1 pp_eexpr e2
|
76
|
| "uminus", _ -> fprintf fmt "(- %a)" pp_eexpr e
|
77
|
| "-", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a - %a)" pp_eexpr e1 pp_eexpr e2
|
78
|
| "*", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a * %a)" pp_eexpr e1 pp_eexpr e2
|
79
|
| "/", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a / %a)" pp_eexpr e1 pp_eexpr e2
|
80
|
| "mod", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a mod %a)" pp_eexpr e1 pp_eexpr e2
|
81
|
| "&&", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a && %a)" pp_eexpr e1 pp_eexpr e2
|
82
|
| "||", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a || %a)" pp_eexpr e1 pp_eexpr e2
|
83
|
| "xor", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a ^^ %a)" pp_eexpr e1 pp_eexpr e2
|
84
|
| "impl", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a ==> %a)" pp_eexpr e1 pp_eexpr e2
|
85
|
| "<", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a < %a)" pp_eexpr e1 pp_eexpr e2
|
86
|
| "<=", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a <= %a)" pp_eexpr e1 pp_eexpr e2
|
87
|
| ">", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a > %a)" pp_eexpr e1 pp_eexpr e2
|
88
|
| ">=", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a >= %a)" pp_eexpr e1 pp_eexpr e2
|
89
|
| "!=", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a != %a)" pp_eexpr e1 pp_eexpr e2
|
90
|
| "=", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a == %a)" pp_eexpr e1 pp_eexpr e2
|
91
|
| "not", _ -> fprintf fmt "(! %a)" pp_eexpr e
|
92
|
| "ite", EExpr_tuple([e1;e2;e3]) -> fprintf fmt "(if %a then %a else %a)" pp_eexpr e1 pp_eexpr e2 pp_eexpr e3
|
93
|
| _ -> fprintf fmt "%s (%a)" id pp_eexpr e)
|
94
|
| Some x -> fprintf fmt "%s (%a) every %s" id pp_eexpr e x
|
95
|
|
96
|
let pp_ensures is_output fmt e =
|
97
|
match e with
|
98
|
| EnsuresExpr e -> fprintf fmt "ensures %a;@ " (pp_eexpr is_output) e
|
99
|
| SpecObserverNode (name, args) -> fprintf fmt "observer %s (%a);@ " name (Utils.fprintf_list ~sep:", " (pp_eexpr is_output)) args
|
100
|
|
101
|
let pp_acsl_spec outputs fmt spec =
|
102
|
let is_output = fun oid -> List.exists (fun v -> v.var_id = oid) outputs in
|
103
|
let pp_eexpr = pp_eexpr is_output in
|
104
|
fprintf fmt "@[<v 2>/*@@ ";
|
105
|
Utils.fprintf_list ~sep:"" (fun fmt r -> fprintf fmt "requires %a;@ " pp_eexpr r) fmt spec.requires;
|
106
|
Utils.fprintf_list ~sep:"" (pp_ensures is_output) fmt spec.ensures;
|
107
|
fprintf fmt "@ ";
|
108
|
(* fprintf fmt "assigns *self%t%a;@ " *)
|
109
|
(* (fun fmt -> if List.length outputs > 0 then fprintf fmt ", ") *)
|
110
|
(* (fprintf_list ~sep:"," (fun fmt v -> fprintf fmt "*%s" v.var_id)) outputs; *)
|
111
|
Utils.fprintf_list ~sep:"@ " (fun fmt (name, assumes, requires) ->
|
112
|
fprintf fmt "behavior %s:@[@ %a@ %a@]"
|
113
|
name
|
114
|
(Utils.fprintf_list ~sep:"@ " (fun fmt r -> fprintf fmt "assumes %a;" pp_eexpr r)) assumes
|
115
|
(Utils.fprintf_list ~sep:"@ " (pp_ensures is_output)) requires
|
116
|
) fmt spec.behaviors;
|
117
|
fprintf fmt "@]@ */@.";
|
118
|
()
|
119
|
|
120
|
|
121
|
|
122
|
|
123
|
let print_machine_decl_prefix fmt m =
|
124
|
(* Print specification if any *)
|
125
|
(match m.mspec with
|
126
|
| None -> ()
|
127
|
| Some spec ->
|
128
|
pp_acsl_spec m.mstep.step_outputs fmt spec
|
129
|
)
|
130
|
|
131
|
*)
|
132
|
|
133
|
(* TODO ACSL
|
134
|
Return updates machines (eg with local annotations) and acsl preamble *)
|
135
|
let preprocess_acsl machines = machines, []
|
136
|
|
137
|
(* TODO: This preamble shall be a list of types, axiomatics, predicates, theorems *)
|
138
|
let pp_acsl_preamble fmt preamble =
|
139
|
Format.fprintf fmt "";
|
140
|
()
|
141
|
|
142
|
let pp_spec pp fmt =
|
143
|
fprintf fmt "@[<v>/*%@@[<v>@,%a@]@,*/@]" pp
|
144
|
|
145
|
let pp_spec_cut pp fmt =
|
146
|
fprintf fmt "%a@," (pp_spec pp)
|
147
|
|
148
|
let pp_spec_line pp fmt =
|
149
|
fprintf fmt "//%@ %a@," pp
|
150
|
|
151
|
let pp_requires pp_req fmt =
|
152
|
fprintf fmt "requires %a;" pp_req
|
153
|
|
154
|
let pp_ensures pp_ens fmt =
|
155
|
fprintf fmt "ensures %a;" pp_ens
|
156
|
|
157
|
let pp_assigns pp_asg fmt =
|
158
|
fprintf fmt "assigns %a;" pp_asg
|
159
|
|
160
|
let pp_ghost pp_gho fmt =
|
161
|
fprintf fmt "ghost %a" pp_gho
|
162
|
|
163
|
let pp_assert pp_ast fmt =
|
164
|
fprintf fmt "assert %a;" pp_ast
|
165
|
|
166
|
let pp_mem_valid pp_var fmt (name, var) =
|
167
|
fprintf fmt "%s_valid(%a)" name pp_var var
|
168
|
|
169
|
let pp_mem_valid' = pp_mem_valid pp_print_string
|
170
|
|
171
|
let pp_indirect pp_field fmt (ptr, field) =
|
172
|
fprintf fmt "%s->%a" ptr pp_field field
|
173
|
|
174
|
let pp_indirect' = pp_indirect pp_print_string
|
175
|
|
176
|
let pp_access pp_field fmt (stru, field) =
|
177
|
fprintf fmt "%s.%a" stru pp_field field
|
178
|
|
179
|
let pp_access' = pp_access pp_print_string
|
180
|
|
181
|
let pp_inst self fmt (name, _) =
|
182
|
pp_indirect' fmt (self, name)
|
183
|
|
184
|
let pp_true fmt () =
|
185
|
pp_print_string fmt "\\true"
|
186
|
|
187
|
let pp_separated self fmt =
|
188
|
fprintf fmt "\\separated(@[<h>%s%a@])"
|
189
|
self
|
190
|
(pp_print_list
|
191
|
~pp_prologue:pp_print_comma
|
192
|
~pp_sep:pp_print_comma
|
193
|
(pp_inst self))
|
194
|
|
195
|
let pp_forall pp_l pp_r fmt (l, r) =
|
196
|
fprintf fmt "@[<v 2>\\forall %a;@,%a@]"
|
197
|
pp_l l
|
198
|
pp_r r
|
199
|
|
200
|
let pp_valid =
|
201
|
pp_print_parenthesized
|
202
|
~pp_nil:pp_true
|
203
|
~pp_prologue:(fun fmt () -> pp_print_string fmt "\\valid")
|
204
|
|
205
|
let pp_equal pp_l pp_r fmt (l, r) =
|
206
|
fprintf fmt "%a == %a"
|
207
|
pp_l l
|
208
|
pp_r r
|
209
|
|
210
|
let pp_implies pp_l pp_r fmt (l, r) =
|
211
|
fprintf fmt "%a ==>@ %a"
|
212
|
pp_l l
|
213
|
pp_r r
|
214
|
|
215
|
let pp_and pp_l pp_r fmt (l, r) =
|
216
|
fprintf fmt "%a @ && %a"
|
217
|
pp_l l
|
218
|
pp_r r
|
219
|
|
220
|
let pp_and_l pp_v fmt =
|
221
|
pp_print_list
|
222
|
~pp_open_box:pp_open_vbox0
|
223
|
~pp_sep:(fun fmt () -> fprintf fmt "@,&& ")
|
224
|
pp_v
|
225
|
fmt
|
226
|
|
227
|
let pp_machine_decl fmt (id, mem_type, var) =
|
228
|
fprintf fmt "struct %s_%s %s" id mem_type var
|
229
|
|
230
|
let pp_mem_ghost pp_mem pp_self ?i fmt (name, mem, self) =
|
231
|
fprintf fmt "%s_ghost%a(%a, %a)"
|
232
|
name
|
233
|
(pp_print_option pp_print_int) i
|
234
|
pp_mem mem
|
235
|
pp_self self
|
236
|
|
237
|
let pp_mem_ghost' = pp_mem_ghost pp_print_string pp_print_string
|
238
|
|
239
|
let pp_mem_init fmt (name, mem) =
|
240
|
fprintf fmt "%s_init(%s)" name mem
|
241
|
|
242
|
let pp_var_decl fmt v =
|
243
|
pp_print_string fmt v.var_id
|
244
|
|
245
|
let pp_ptr_decl fmt v =
|
246
|
fprintf fmt "*%s" v.var_id
|
247
|
|
248
|
let pp_mem_trans ?i fmt (m, mem_in, mem_out) =
|
249
|
fprintf fmt "%s_trans%a(@[<h>%s, %a%s%a@])"
|
250
|
m.mname.node_id
|
251
|
(pp_print_option pp_print_int) i
|
252
|
mem_in
|
253
|
(pp_print_list
|
254
|
~pp_epilogue:pp_print_comma
|
255
|
~pp_sep:pp_print_comma
|
256
|
pp_var_decl) m.mstep.step_inputs
|
257
|
mem_out
|
258
|
(pp_print_list
|
259
|
~pp_prologue:pp_print_comma
|
260
|
~pp_sep:pp_print_comma
|
261
|
pp_ptr_decl) m.mstep.step_outputs
|
262
|
|
263
|
let pp_nothing fmt () =
|
264
|
pp_print_string fmt "\\nothing"
|
265
|
|
266
|
let pp_predicate pp_l pp_r fmt (l, r) =
|
267
|
fprintf fmt "@[<v 2>predicate %a =@,%a;@]"
|
268
|
pp_l l
|
269
|
pp_r r
|
270
|
|
271
|
let print_machine_valid_predicate fmt m =
|
272
|
if not (fst (Machine_code_common.get_stateless_status m)) then
|
273
|
let name = m.mname.node_id in
|
274
|
let self = mk_self m in
|
275
|
pp_spec
|
276
|
(pp_predicate
|
277
|
(pp_mem_valid pp_machine_decl)
|
278
|
(pp_and
|
279
|
(pp_and_l (fun fmt (_, (td, _) as inst) ->
|
280
|
pp_mem_valid (pp_inst self) fmt (node_name td, inst)))
|
281
|
(pp_valid pp_print_string)))
|
282
|
fmt
|
283
|
((name, (name, "mem", "*" ^ self)),
|
284
|
(m.minstances, [self]))
|
285
|
|
286
|
let print_machine_ghost_simulation_aux ?i m pp fmt v =
|
287
|
let name = m.mname.node_id in
|
288
|
let self = mk_self m in
|
289
|
let mem = mk_mem m in
|
290
|
pp_spec
|
291
|
(pp_predicate
|
292
|
(pp_mem_ghost pp_machine_decl pp_machine_decl ?i)
|
293
|
pp)
|
294
|
fmt
|
295
|
((name, (name, "mem_ghost", mem), (name, "mem", "*" ^ self)),
|
296
|
v)
|
297
|
|
298
|
let print_machine_ghost_simulation dependencies m fmt i instr =
|
299
|
let name = m.mname.node_id in
|
300
|
let self = mk_self m in
|
301
|
let mem = mk_mem m in
|
302
|
let prev_ghost fmt () = pp_mem_ghost' ~i fmt (name, mem, self) in
|
303
|
let pred pp v = pp_and prev_ghost pp fmt ((), v) in
|
304
|
print_machine_ghost_simulation_aux m
|
305
|
(fun fmt -> function
|
306
|
| MStateAssign (m, _) ->
|
307
|
pred
|
308
|
(pp_equal
|
309
|
(pp_access (pp_access pp_var_decl))
|
310
|
(pp_indirect (pp_access pp_var_decl)))
|
311
|
((mem, ("_reg", m)),
|
312
|
(self, ("_reg", m)))
|
313
|
| MStep ([i0], i, vl)
|
314
|
when Basic_library.is_value_internal_fun
|
315
|
(mk_val (Fun (i, vl)) i0.var_type) ->
|
316
|
prev_ghost fmt ()
|
317
|
| MStep (_, i, _) when !Options.mpfr && Mpfr.is_homomorphic_fun i ->
|
318
|
prev_ghost fmt ()
|
319
|
| MStep ([_], i, _) when has_c_prototype i dependencies ->
|
320
|
prev_ghost fmt ()
|
321
|
| MStep (_, i, _)
|
322
|
| MReset i ->
|
323
|
begin try
|
324
|
let n, _ = List.assoc i m.minstances in
|
325
|
pred
|
326
|
(pp_mem_ghost pp_access' pp_indirect')
|
327
|
(node_name n, (mem, i), (self, i))
|
328
|
with Not_found -> prev_ghost fmt ()
|
329
|
end
|
330
|
| _ -> prev_ghost fmt ())
|
331
|
~i:(i+1) fmt instr.instr_desc
|
332
|
|
333
|
let print_machine_ghost_struct fmt m =
|
334
|
pp_spec (pp_ghost (print_machine_struct ~ghost:true)) fmt m
|
335
|
|
336
|
let print_machine_ghost_simulations dependencies fmt m =
|
337
|
if not (fst (Machine_code_common.get_stateless_status m)) then
|
338
|
let name = m.mname.node_id in
|
339
|
let self = mk_self m in
|
340
|
let mem = mk_mem m in
|
341
|
fprintf fmt "%a@,%a@,%a%a"
|
342
|
print_machine_ghost_struct m
|
343
|
(print_machine_ghost_simulation_aux m pp_true ~i:0) ()
|
344
|
(pp_print_list_i
|
345
|
~pp_epilogue:pp_print_cut
|
346
|
~pp_open_box:pp_open_vbox0
|
347
|
(print_machine_ghost_simulation dependencies m))
|
348
|
m.mstep.step_instrs
|
349
|
(print_machine_ghost_simulation_aux m
|
350
|
(pp_mem_ghost' ~i:(List.length m.mstep.step_instrs))) (name, mem, self)
|
351
|
|
352
|
let pp_at pp_p fmt (p, l) =
|
353
|
fprintf fmt "\\at(%a, %s)" pp_p p l
|
354
|
|
355
|
let label_pre = "Pre"
|
356
|
|
357
|
let pp_at_pre pp_p fmt p =
|
358
|
pp_at pp_p fmt (p, label_pre)
|
359
|
|
360
|
module SrcMod = struct
|
361
|
|
362
|
let pp_predicates dependencies fmt machines =
|
363
|
fprintf fmt
|
364
|
"%a%a"
|
365
|
(pp_print_list
|
366
|
~pp_open_box:pp_open_vbox0
|
367
|
~pp_prologue:(pp_print_endcut "/* ACSL `valid` predicates */")
|
368
|
print_machine_valid_predicate
|
369
|
~pp_epilogue:pp_print_cutcut) machines
|
370
|
(pp_print_list
|
371
|
~pp_open_box:pp_open_vbox0
|
372
|
~pp_sep:pp_print_cutcut
|
373
|
~pp_prologue:(fun fmt () -> fprintf fmt
|
374
|
"/* ACSL ghost simulations */@,%a"
|
375
|
(pp_spec_line (pp_ghost pp_print_string))
|
376
|
"struct _arrow_mem_ghost {struct _arrow_reg _reg;};")
|
377
|
(print_machine_ghost_simulations dependencies)
|
378
|
~pp_epilogue:pp_print_cutcut) machines
|
379
|
|
380
|
let pp_reset_spec fmt self m =
|
381
|
let name = m.mname.node_id in
|
382
|
let mem = mk_mem m in
|
383
|
pp_spec_cut (fun fmt () ->
|
384
|
fprintf fmt
|
385
|
"%a@,%a@,%a@,%a"
|
386
|
(pp_requires pp_mem_valid') (name, self)
|
387
|
(pp_requires (pp_separated self)) m.minstances
|
388
|
(pp_assigns
|
389
|
(pp_print_list
|
390
|
~pp_sep:pp_print_comma
|
391
|
~pp_nil:pp_nothing
|
392
|
(pp_inst self))) m.minstances
|
393
|
(pp_ensures
|
394
|
(pp_forall
|
395
|
pp_machine_decl
|
396
|
(pp_implies
|
397
|
pp_mem_ghost'
|
398
|
pp_mem_init)))
|
399
|
((name, "mem_ghost", mem),
|
400
|
((name, mem, self), (name, mem))))
|
401
|
fmt ()
|
402
|
|
403
|
let pp_step_spec fmt self m =
|
404
|
let name = m.mname.node_id in
|
405
|
let mem_in = mk_mem_in m in
|
406
|
let mem_out = mk_mem_out m in
|
407
|
pp_spec_cut (fun fmt () ->
|
408
|
fprintf fmt
|
409
|
"%a@,%a@,%a@,%a@,%a"
|
410
|
(pp_requires (pp_valid pp_var_decl)) m.mstep.step_outputs
|
411
|
(pp_requires pp_mem_valid') (name, self)
|
412
|
(pp_requires (pp_separated self)) m.minstances
|
413
|
(pp_assigns
|
414
|
(if m.mstep.step_outputs = [] && m.minstances = [] then
|
415
|
pp_nothing
|
416
|
else
|
417
|
fun fmt () ->
|
418
|
fprintf fmt "@[<h>%a%a@]"
|
419
|
(pp_print_list
|
420
|
~pp_sep:pp_print_comma
|
421
|
~pp_epilogue:pp_print_comma
|
422
|
pp_ptr_decl) m.mstep.step_outputs
|
423
|
(pp_print_list
|
424
|
~pp_sep:pp_print_comma
|
425
|
(pp_inst self)) m.minstances)) ()
|
426
|
(pp_ensures
|
427
|
(pp_forall
|
428
|
(fun fmt () ->
|
429
|
fprintf fmt "%a, %s"
|
430
|
pp_machine_decl (name, "mem_ghost", mem_in)
|
431
|
mem_out)
|
432
|
(pp_implies
|
433
|
(pp_at_pre pp_mem_ghost')
|
434
|
(pp_implies
|
435
|
pp_mem_ghost'
|
436
|
pp_mem_trans))))
|
437
|
((),
|
438
|
((name, mem_in, self),
|
439
|
((name, mem_out, self),
|
440
|
(m, mem_in, mem_out)))))
|
441
|
fmt ()
|
442
|
|
443
|
let pp_step_instr_spec m self fmt (i, instr) =
|
444
|
let name = m.mname.node_id in
|
445
|
let mem_in = mk_mem_in m in
|
446
|
let mem_out = mk_mem_out m in
|
447
|
fprintf fmt "@,%a"
|
448
|
(pp_spec
|
449
|
(pp_assert
|
450
|
(pp_forall
|
451
|
(fun fmt () ->
|
452
|
fprintf fmt "%a, %s"
|
453
|
pp_machine_decl (name, "mem_ghost", mem_in)
|
454
|
mem_out)
|
455
|
(pp_implies
|
456
|
(pp_at_pre pp_mem_ghost')
|
457
|
(pp_implies
|
458
|
(pp_mem_ghost' ~i:(i+1))
|
459
|
(pp_mem_trans ~i:(i+1)))))))
|
460
|
((),
|
461
|
((name, mem_in, self),
|
462
|
((name, mem_out, self),
|
463
|
(m, mem_in, mem_out))))
|
464
|
|
465
|
end
|
466
|
|
467
|
(**************************************************************************)
|
468
|
(* MAKEFILE *)
|
469
|
(**************************************************************************)
|
470
|
|
471
|
module MakefileMod = struct
|
472
|
|
473
|
let other_targets fmt basename _nodename dependencies =
|
474
|
fprintf fmt "FRAMACEACSL=`frama-c -print-share-path`/e-acsl@.";
|
475
|
(* EACSL version of library file . c *)
|
476
|
fprintf fmt "%s_eacsl.c: %s.c %s.h@." basename basename basename;
|
477
|
fprintf fmt
|
478
|
"\tframa-c -e-acsl-full-mmodel -machdep x86_64 -e-acsl %s.c -then-on e-acsl -print -ocode %s_eacsl.c@."
|
479
|
basename basename;
|
480
|
fprintf fmt "@.";
|
481
|
fprintf fmt "@.";
|
482
|
|
483
|
(* EACSL version of library file . c + main .c *)
|
484
|
fprintf fmt "%s_main_eacsl.c: %s.c %s.h %s_main.c@." basename basename basename basename;
|
485
|
fprintf fmt "\tframa-c -e-acsl-full-mmodel -machdep x86_64 -e-acsl %s.c %s_main.c -then-on e-acsl -print -ocode %s_main_eacsl.i@."
|
486
|
basename basename basename;
|
487
|
(* Ugly hack to deal with eacsl bugs *)
|
488
|
fprintf fmt "\tgrep -v _fc_stdout %s_main_eacsl.i > %s_main_eacsl.c" basename basename;
|
489
|
fprintf fmt "@.";
|
490
|
fprintf fmt "@.";
|
491
|
|
492
|
(* EACSL version of binary *)
|
493
|
fprintf fmt "%s_main_eacsl: %s_main_eacsl.c@." basename basename;
|
494
|
fprintf fmt "\t${GCC} -Wno-attributes -I${INC} -I. -c %s_main_eacsl.c@." basename; (* compiling instrumented lib + main *)
|
495
|
C_backend_makefile.fprintf_dependencies fmt dependencies;
|
496
|
fprintf fmt "\t${GCC} -Wno-attributes -o %s_main_eacsl io_frontend.o %a %s %s_main_eacsl.o %a@."
|
497
|
basename
|
498
|
(Utils.fprintf_list ~sep:" " (fun fmt dep -> Format.fprintf fmt "%s.o" dep.name))
|
499
|
(C_backend_makefile.compiled_dependencies dependencies)
|
500
|
("${FRAMACEACSL}/e_acsl.c "
|
501
|
^ "${FRAMACEACSL}/memory_model/e_acsl_bittree.c "
|
502
|
^ "${FRAMACEACSL}/memory_model/e_acsl_mmodel.c")
|
503
|
basename
|
504
|
(Utils.fprintf_list ~sep:" " (fun fmt lib -> fprintf fmt "-l%s" lib))
|
505
|
(C_backend_makefile.lib_dependencies dependencies)
|
506
|
;
|
507
|
fprintf fmt "@."
|
508
|
|
509
|
end
|
510
|
|
511
|
(* Local Variables: *)
|
512
|
(* compile-command:"make -C ../../.." *)
|
513
|
(* End: *)
|