Revision 90cc3b8e
Added by LĂ©lio Brun over 3 years ago
src/backends/C/c_backend_main.ml | ||
---|---|---|
12 | 12 |
open Lustre_types |
13 | 13 |
open Machine_code_types |
14 | 14 |
open Machine_code_common |
15 |
open Format |
|
15 |
open Utils.Format
|
|
16 | 16 |
open C_backend_common |
17 | 17 |
open Utils |
18 | 18 |
|
19 |
module type MODIFIERS_MAINSRC = |
|
20 |
sig |
|
19 |
module type MODIFIERS_MAINSRC = sig |
|
21 | 20 |
end |
22 | 21 |
|
23 |
module EmptyMod = |
|
24 |
struct |
|
22 |
module EmptyMod = struct |
|
25 | 23 |
end |
26 | 24 |
|
27 |
module Main = functor (Mod: MODIFIERS_MAINSRC) -> |
|
28 |
struct |
|
25 |
module Main = functor (Mod: MODIFIERS_MAINSRC) -> struct |
|
29 | 26 |
|
30 |
(********************************************************************************************) |
|
31 |
(* Main related functions *) |
|
32 |
(********************************************************************************************) |
|
27 |
(********************************************************************************************)
|
|
28 |
(* Main related functions *)
|
|
29 |
(********************************************************************************************)
|
|
33 | 30 |
|
31 |
let pp_c_main_var_input fmt id = |
|
32 |
fprintf fmt "%s" id.var_id |
|
34 | 33 |
|
35 |
let print_put_outputs fmt m = |
|
36 |
let po fmt (id, o', o) = |
|
37 |
let suff = string_of_int id in |
|
34 |
let pp_c_main_var_output fmt id = |
|
35 |
if Types.is_address_type id.var_type |
|
36 |
then |
|
37 |
fprintf fmt "%s" id.var_id |
|
38 |
else |
|
39 |
fprintf fmt "&%s" id.var_id |
|
40 |
|
|
41 |
let print_put_output fmt id o' o = |
|
42 |
let suff = string_of_int (id + 1) in |
|
38 | 43 |
print_put_var fmt suff o'.var_id o.var_type o.var_id |
39 |
in |
|
40 |
List.iteri2 (fun idx v' v -> fprintf fmt "@ %a;" po ((idx+1), v', v)) m.mname.node_outputs m.mstep.step_outputs |
|
41 |
|
|
42 |
|
|
43 |
let print_main_inout_declaration m fmt = |
|
44 |
fprintf fmt "/* Declaration of inputs/outputs variables */@ "; |
|
45 |
List.iteri (fun idx v -> |
|
46 |
fprintf fmt "%a;@ " (pp_c_type v.var_id) v.var_type; |
|
47 |
ignore (pp_file_decl fmt "in" idx) |
|
48 |
) m.mstep.step_inputs; |
|
49 |
List.iteri (fun idx v -> |
|
50 |
fprintf fmt "%a;@ " (pp_c_type v.var_id) v.var_type; |
|
51 |
ignore (pp_file_decl fmt "out" idx) |
|
52 |
) m.mstep.step_outputs; |
|
53 |
fprintf fmt "@[<v 2>if (traces) {@ "; |
|
54 |
List.iteri (fun idx _ -> |
|
55 |
ignore (pp_file_open fmt "in" idx) |
|
56 |
) m.mstep.step_inputs; |
|
57 |
List.iteri (fun idx _ -> |
|
58 |
ignore (pp_file_open fmt "out" idx) |
|
59 |
) m.mstep.step_outputs; |
|
60 |
fprintf fmt "@]}@ " |
|
61 |
|
|
62 |
|
|
63 |
let print_main_memory_allocation mname main_mem fmt m = |
|
64 |
if not (fst (get_stateless_status m)) then |
|
65 |
begin |
|
66 |
fprintf fmt "@ /* Main memory allocation */@ "; |
|
67 |
if (!Options.static_mem && !Options.main_node <> "") |
|
68 |
then (fprintf fmt "%a(static,main_mem);@ " pp_machine_static_alloc_name mname) |
|
69 |
else (fprintf fmt "%a *main_mem = %a();@ " pp_machine_memtype_name mname pp_machine_alloc_name mname); |
|
70 |
fprintf fmt "@ /* Initialize the main memory */@ "; |
|
71 |
fprintf fmt "%a(%s);@ " pp_machine_reset_name mname main_mem; |
|
72 |
end |
|
73 |
|
|
74 |
let print_global_initialize fmt basename = |
|
75 |
let mNAME = file_to_module_name basename in |
|
76 |
fprintf fmt "@ /* Initialize global constants */@ %a();@ " |
|
77 |
pp_global_init_name mNAME |
|
78 |
|
|
79 |
let print_global_clear fmt basename = |
|
80 |
let mNAME = file_to_module_name basename in |
|
81 |
fprintf fmt "@ /* Clear global constants */@ %a();@ " |
|
82 |
pp_global_clear_name mNAME |
|
83 |
|
|
84 |
let print_main_initialize mname main_mem fmt m = |
|
85 |
if not (fst (get_stateless_status m)) |
|
86 |
then |
|
87 |
fprintf fmt "@ /* Initialize inputs, outputs and memories */@ %a%t%a%t%a(%s);@ " |
|
88 |
(Utils.fprintf_list ~sep:"@ " (pp_initialize m main_mem (pp_c_var_read m))) m.mstep.step_inputs |
|
89 |
(Utils.pp_newline_if_non_empty m.mstep.step_inputs) |
|
90 |
(Utils.fprintf_list ~sep:"@ " (pp_initialize m main_mem (pp_c_var_read m))) m.mstep.step_outputs |
|
91 |
(Utils.pp_newline_if_non_empty m.mstep.step_inputs) |
|
92 |
pp_machine_init_name mname |
|
93 |
main_mem |
|
94 |
else |
|
95 |
fprintf fmt "@ /* Initialize inputs and outputs */@ %a%t%a@ " |
|
96 |
(Utils.fprintf_list ~sep:"@ " (pp_initialize m main_mem (pp_c_var_read m))) m.mstep.step_inputs |
|
97 |
(Utils.pp_newline_if_non_empty m.mstep.step_inputs) |
|
98 |
(Utils.fprintf_list ~sep:"@ " (pp_initialize m main_mem (pp_c_var_read m))) m.mstep.step_outputs |
|
99 | 44 |
|
100 |
let print_main_clear mname main_mem fmt m = |
|
101 |
if not (fst (get_stateless_status m)) |
|
45 |
let print_main_inout_declaration fmt m = |
|
46 |
fprintf fmt |
|
47 |
"/* Declaration of inputs/outputs variables */@,\ |
|
48 |
%a%a\ |
|
49 |
@[<v 2>if (traces) {@,\ |
|
50 |
%a%a@]@,\ |
|
51 |
}" |
|
52 |
(pp_print_list_i |
|
53 |
~pp_open_box:pp_open_vbox0 |
|
54 |
~pp_epilogue:pp_print_cut |
|
55 |
(fun fmt idx v -> |
|
56 |
fprintf fmt "%a; %a" |
|
57 |
(pp_c_type v.var_id) v.var_type |
|
58 |
(fun fmt () -> pp_file_decl fmt "in" idx) ())) m.mstep.step_inputs |
|
59 |
(pp_print_list_i |
|
60 |
~pp_open_box:pp_open_vbox0 |
|
61 |
~pp_epilogue:pp_print_cut |
|
62 |
(fun fmt idx v -> |
|
63 |
fprintf fmt "%a; %a" |
|
64 |
(pp_c_type v.var_id) v.var_type |
|
65 |
(fun fmt () -> pp_file_decl fmt "out" idx) ())) m.mstep.step_outputs |
|
66 |
(pp_print_list_i |
|
67 |
~pp_epilogue:pp_print_cut |
|
68 |
(fun fmt idx _ -> |
|
69 |
ignore (pp_file_open fmt "in" idx))) m.mstep.step_inputs |
|
70 |
(pp_print_list_i |
|
71 |
(fun fmt idx _ -> |
|
72 |
ignore (pp_file_open fmt "out" idx))) m.mstep.step_outputs |
|
73 |
|
|
74 |
let print_main_memory_allocation mname main_mem fmt m = |
|
75 |
if not (fst (get_stateless_status m)) then |
|
76 |
fprintf fmt |
|
77 |
"@[<v>/* Main memory allocation */@,\ |
|
78 |
%a@,\ |
|
79 |
@,\ |
|
80 |
/* Initialize the main memory */@,\ |
|
81 |
%a(%s);@]" |
|
82 |
(fun fmt () -> |
|
83 |
if !Options.static_mem && !Options.main_node <> "" then |
|
84 |
fprintf fmt "%a(static,main_mem);" |
|
85 |
pp_machine_static_alloc_name mname |
|
86 |
else |
|
87 |
fprintf fmt "%a *main_mem = %a();" |
|
88 |
pp_machine_memtype_name mname |
|
89 |
pp_machine_alloc_name mname) () |
|
90 |
pp_machine_reset_name mname |
|
91 |
main_mem |
|
92 |
|
|
93 |
let print_global_initialize fmt basename = |
|
94 |
let mNAME = file_to_module_name basename in |
|
95 |
fprintf fmt "/* Initialize global constants */@,%a();" |
|
96 |
pp_global_init_name mNAME |
|
97 |
|
|
98 |
let print_global_clear fmt basename = |
|
99 |
let mNAME = file_to_module_name basename in |
|
100 |
fprintf fmt "/* Clear global constants */@,%a();" |
|
101 |
pp_global_clear_name mNAME |
|
102 |
|
|
103 |
let print_main_initialize mname main_mem fmt m = |
|
104 |
let inputs = mpfr_vars m.mstep.step_inputs in |
|
105 |
let outputs = mpfr_vars m.mstep.step_outputs in |
|
106 |
if not (fst (get_stateless_status m)) |
|
107 |
then |
|
108 |
fprintf fmt |
|
109 |
"/* Initialize inputs, outputs and memories */@,\ |
|
110 |
%a%a%a(%s);" |
|
111 |
(pp_print_list |
|
112 |
~pp_open_box:pp_open_vbox0 |
|
113 |
~pp_eol:pp_print_cut |
|
114 |
(pp_initialize m main_mem (pp_c_var_read m))) inputs |
|
115 |
(pp_print_list |
|
116 |
~pp_open_box:pp_open_vbox0 |
|
117 |
~pp_eol:pp_print_cut |
|
118 |
(pp_initialize m main_mem (pp_c_var_read m))) outputs |
|
119 |
pp_machine_init_name mname |
|
120 |
main_mem |
|
121 |
else |
|
122 |
fprintf fmt |
|
123 |
"/* Initialize inputs and outputs */@,\ |
|
124 |
%a%a@ " |
|
125 |
(pp_print_list |
|
126 |
~pp_open_box:pp_open_vbox0 |
|
127 |
~pp_eol:pp_print_cut |
|
128 |
(pp_initialize m main_mem (pp_c_var_read m))) inputs |
|
129 |
(pp_print_list |
|
130 |
~pp_open_box:pp_open_vbox0 |
|
131 |
(pp_initialize m main_mem (pp_c_var_read m))) outputs |
|
132 |
|
|
133 |
let print_main_clear mname main_mem fmt m = |
|
134 |
let inputs = mpfr_vars m.mstep.step_inputs in |
|
135 |
let outputs = mpfr_vars m.mstep.step_outputs in |
|
136 |
if not (fst (get_stateless_status m)) |
|
137 |
then |
|
138 |
fprintf fmt |
|
139 |
"@[<v>/* Clear inputs, outputs and memories */@,\ |
|
140 |
%a%a%a(%s);@]" |
|
141 |
(pp_print_list |
|
142 |
~pp_open_box:pp_open_vbox0 |
|
143 |
~pp_eol:pp_print_cut |
|
144 |
(pp_clear m main_mem (pp_c_var_read m))) inputs |
|
145 |
(pp_print_list |
|
146 |
~pp_open_box:pp_open_vbox0 |
|
147 |
~pp_eol:pp_print_cut |
|
148 |
(pp_clear m main_mem (pp_c_var_read m))) outputs |
|
149 |
pp_machine_clear_name mname |
|
150 |
main_mem |
|
151 |
else |
|
152 |
fprintf fmt |
|
153 |
"@[<v>/* Clear inputs and outputs */@,\ |
|
154 |
%a%a@]" |
|
155 |
(pp_print_list |
|
156 |
~pp_open_box:pp_open_vbox0 |
|
157 |
~pp_eol:pp_print_cut |
|
158 |
(pp_clear m main_mem (pp_c_var_read m))) inputs |
|
159 |
(pp_print_list |
|
160 |
~pp_open_box:pp_open_vbox0 |
|
161 |
(pp_clear m main_mem (pp_c_var_read m))) outputs |
|
162 |
|
|
163 |
let print_get_input fmt id v' v = |
|
164 |
let pp_file = pp_print_file ("in" ^ string_of_int (id + 1)) in |
|
165 |
let unclocked_t = Types.unclock_type v.var_type in |
|
166 |
fprintf fmt "@[<v>%a@]" |
|
167 |
(fun fmt () -> |
|
168 |
if Types.is_int_type unclocked_t then |
|
169 |
fprintf fmt "%s = _get_int(\"%s\");@,%a" |
|
170 |
v.var_id v'.var_id |
|
171 |
pp_file ("d", v.var_id) |
|
172 |
else if Types.is_bool_type unclocked_t then |
|
173 |
fprintf fmt "%s = _get_bool(\"%s\");@,%a" |
|
174 |
v.var_id v'.var_id |
|
175 |
pp_file ("i", v.var_id) |
|
176 |
else if Types.is_real_type unclocked_t then |
|
177 |
if !Options.mpfr then |
|
178 |
fprintf fmt "double %s_tmp = _get_double(\"%s\");@,\ |
|
179 |
%a@,\ |
|
180 |
mpfr_set_d(%s, %s_tmp, %i);" |
|
181 |
v.var_id v'.var_id |
|
182 |
pp_file ("f", v.var_id ^ "_tmp") |
|
183 |
v.var_id v.var_id (Mpfr.mpfr_prec ()) |
|
184 |
else |
|
185 |
fprintf fmt "%s = _get_double(\"%s\");@,%a" |
|
186 |
v.var_id v'.var_id |
|
187 |
pp_file ("f", v.var_id) |
|
188 |
else begin |
|
189 |
Global.main_node := !Options.main_node; |
|
190 |
eprintf "Code generation error: %a%a@." |
|
191 |
Error.pp_error_msg Error.Main_wrong_kind |
|
192 |
Location.pp_loc v'.var_loc; |
|
193 |
raise (Error.Error (v'.var_loc, Error.Main_wrong_kind)) |
|
194 |
end) () |
|
195 |
|
|
196 |
let pp_main_call mname self fmt m (inputs: value_t list) (outputs: var_decl list) = |
|
197 |
if fst (Machine_code_common.get_stateless_status m) |
|
102 | 198 |
then |
103 |
fprintf fmt "@ /* Clear inputs, outputs and memories */@ %a%t%a%t%a(%s);@ " |
|
104 |
(Utils.fprintf_list ~sep:"@ " (pp_clear m main_mem (pp_c_var_read m))) m.mstep.step_inputs |
|
105 |
(Utils.pp_newline_if_non_empty m.mstep.step_inputs) |
|
106 |
(Utils.fprintf_list ~sep:"@ " (pp_clear m main_mem (pp_c_var_read m))) m.mstep.step_outputs |
|
107 |
(Utils.pp_newline_if_non_empty m.mstep.step_inputs) |
|
108 |
pp_machine_clear_name mname |
|
109 |
main_mem |
|
199 |
fprintf fmt "%a (%a%a);" |
|
200 |
pp_machine_step_name mname |
|
201 |
(pp_print_list ~pp_sep:pp_print_comma ~pp_eol:pp_print_comma |
|
202 |
(pp_c_val m self pp_c_main_var_input)) inputs |
|
203 |
(pp_print_list ~pp_sep:pp_print_comma pp_c_main_var_output) outputs |
|
110 | 204 |
else |
111 |
fprintf fmt "@ /* Clear inputs and outputs */@ %a%t%a@ " |
|
112 |
(Utils.fprintf_list ~sep:"@ " (pp_clear m main_mem (pp_c_var_read m))) m.mstep.step_inputs |
|
113 |
(Utils.pp_newline_if_non_empty m.mstep.step_inputs) |
|
114 |
(Utils.fprintf_list ~sep:"@ " (pp_clear m main_mem (pp_c_var_read m))) m.mstep.step_outputs |
|
115 |
|
|
116 |
let print_main_loop mname main_mem fmt m = |
|
117 |
let input_values = |
|
118 |
List.map (fun v -> mk_val (Var v) v.var_type) |
|
119 |
m.mstep.step_inputs in |
|
120 |
begin |
|
121 |
fprintf fmt "@ ISATTY = isatty(0);@ "; |
|
122 |
fprintf fmt "@ /* Infinite loop */@ "; |
|
123 |
fprintf fmt "@[<v 2>while(1){@ "; |
|
124 |
fprintf fmt "fflush(stdout);@ "; |
|
125 |
fprintf fmt "@[<v 2>if (traces) {@ "; |
|
126 |
List.iteri (fun idx _ -> fprintf fmt "fflush(f_in%i);@ " (idx+1)) m.mstep.step_inputs; |
|
127 |
List.iteri (fun idx _ -> fprintf fmt "fflush(f_out%i);@ " (idx+1)) m.mstep.step_outputs; |
|
128 |
fprintf fmt "@]}@ "; |
|
129 |
fprintf fmt "%a@ %t%a" |
|
130 |
print_get_inputs m |
|
131 |
(fun fmt -> pp_main_call mname main_mem fmt m input_values m.mstep.step_outputs) |
|
132 |
print_put_outputs m |
|
133 |
end |
|
134 |
|
|
135 |
let print_usage fmt = |
|
136 |
fprintf fmt "@[<v 2>void usage(char *argv[]) {@ "; |
|
137 |
fprintf fmt "printf(\"Usage: %%s\\n\", argv[0]);@ "; |
|
138 |
fprintf fmt "printf(\" -t: produce trace files for input/output flows\\n\");@ "; |
|
139 |
fprintf fmt "printf(\" -d<dir>: directory containing traces (default: _traces)\\n\");@ "; |
|
140 |
fprintf fmt "printf(\" -p<prefix>: prefix_simu.scope<id> (default: file_node)\\n\");@ "; |
|
141 |
fprintf fmt "exit (8);@ "; |
|
142 |
fprintf fmt "@]}@ " |
|
143 |
|
|
144 |
let print_options fmt name = |
|
145 |
fprintf fmt "int traces = 0;@ "; |
|
146 |
fprintf fmt "char* prefix = \"%s\";@ " name; |
|
147 |
fprintf fmt "char* dir = \".\";@ "; |
|
148 |
fprintf fmt "@[<v 2>while ((argc > 1) && (argv[1][0] == '-')) {@ "; |
|
149 |
fprintf fmt "@[<v 2>switch (argv[1][1]) {@ "; |
|
150 |
fprintf fmt "@[<v 2>case 't':@ "; |
|
151 |
fprintf fmt "traces = 1;@ "; |
|
152 |
fprintf fmt "break;@ "; |
|
153 |
fprintf fmt "@]@ "; |
|
154 |
fprintf fmt "@[<v 2>case 'd':@ "; |
|
155 |
fprintf fmt "dir = &argv[1][2];@ "; |
|
156 |
fprintf fmt "break;@ "; |
|
157 |
fprintf fmt "@]@ "; |
|
158 |
fprintf fmt "@[<v 2>case 'p':@ "; |
|
159 |
fprintf fmt "prefix = &argv[1][2];@ "; |
|
160 |
fprintf fmt "break;@ "; |
|
161 |
fprintf fmt "@]@ "; |
|
162 |
fprintf fmt "@[<v 2>default:@ "; |
|
163 |
fprintf fmt "printf(\"Wrong Argument: %%s\\n\", argv[1]);@ "; |
|
164 |
fprintf fmt "usage(argv);@ "; |
|
165 |
fprintf fmt "@]@ "; |
|
166 |
fprintf fmt "@]}@ "; |
|
167 |
fprintf fmt "++argv;@ "; |
|
168 |
fprintf fmt "--argc;@ "; |
|
169 |
fprintf fmt "@]}@ " |
|
170 |
|
|
171 |
let print_main_code fmt basename m = |
|
172 |
let mname = m.mname.node_id in |
|
173 |
(* TODO: find a proper way to shorthen long names. This causes segfault in the binary when trying to fprintf in them *) |
|
174 |
let mname = if String.length mname > 50 then string_of_int (Hashtbl.hash mname) else mname in |
|
175 |
|
|
176 |
let main_mem = |
|
177 |
if (!Options.static_mem && !Options.main_node <> "") |
|
178 |
then "&main_mem" |
|
179 |
else "main_mem" in |
|
180 |
print_usage fmt; |
|
181 |
|
|
182 |
fprintf fmt "@[<v 2>int main (int argc, char *argv[]) {@ "; |
|
183 |
print_options fmt (basename ^ "_" ^ mname); |
|
184 |
print_main_inout_declaration m fmt; |
|
185 |
Plugins.c_backend_main_loop_body_prefix basename mname fmt (); |
|
186 |
print_main_memory_allocation mname main_mem fmt m; |
|
187 |
if !Options.mpfr then |
|
188 |
begin |
|
189 |
print_global_initialize fmt basename; |
|
190 |
print_main_initialize mname main_mem fmt m; |
|
191 |
end; |
|
192 |
print_main_loop mname main_mem fmt m; |
|
193 |
|
|
194 |
Plugins.c_backend_main_loop_body_suffix fmt (); |
|
195 |
fprintf fmt "@]@ }@ @ "; |
|
196 |
if !Options.mpfr then |
|
197 |
begin |
|
198 |
print_main_clear mname main_mem fmt m; |
|
199 |
print_global_clear fmt basename; |
|
200 |
end; |
|
201 |
fprintf fmt "@ return 1;"; |
|
202 |
fprintf fmt "@]@ }@." |
|
203 |
|
|
204 |
let print_main_header fmt = |
|
205 |
fprintf fmt (if !Options.cpp then "#include <stdio.h>@.#include <unistd.h>@.#include \"%s/io_frontend.hpp\"@." else "#include <stdio.h>@.#include <unistd.h>@.#include <string.h>@.#include \"%s/io_frontend.h\"@.") |
|
206 |
(Options_management.core_dependency "io_frontend") |
|
207 |
|
|
208 |
let print_main_c main_fmt main_machine basename _prog _machines _dependencies = |
|
209 |
print_main_header main_fmt; |
|
210 |
fprintf main_fmt "#include <stdlib.h>@.#include <assert.h>@."; |
|
211 |
print_import_alloc_prototype main_fmt {local=true; name=basename; content=[]; is_stateful=true} (* assuming it is stateful*) ; |
|
212 |
pp_print_newline main_fmt (); |
|
213 |
|
|
214 |
(* Print the svn version number and the supported C standard (C90 or C99) *) |
|
215 |
print_version main_fmt; |
|
216 |
print_main_code main_fmt basename main_machine |
|
217 |
end |
|
205 |
fprintf fmt "%a (%a%a%s);" |
|
206 |
pp_machine_step_name mname |
|
207 |
(pp_print_list ~pp_sep:pp_print_comma ~pp_eol:pp_print_comma |
|
208 |
(pp_c_val m self pp_c_main_var_input)) inputs |
|
209 |
(pp_print_list ~pp_sep:pp_print_comma ~pp_eol:pp_print_comma |
|
210 |
pp_c_main_var_output) outputs |
|
211 |
self |
|
212 |
|
|
213 |
let print_main_loop mname main_mem fmt m = |
|
214 |
let input_values = List.map (fun v -> |
|
215 |
mk_val (Var v) v.var_type) m.mstep.step_inputs in |
|
216 |
fprintf fmt |
|
217 |
"ISATTY = isatty(0);@,\ |
|
218 |
@,\ |
|
219 |
/* Infinite loop */@,\ |
|
220 |
@[<v 2>while(1){@,\ |
|
221 |
fflush(stdout);@,\ |
|
222 |
@[<v 2>if (traces) {@,\ |
|
223 |
%a%a\ |
|
224 |
@]@,\ |
|
225 |
}@,\ |
|
226 |
%a%a%a" |
|
227 |
|
|
228 |
(pp_print_list_i |
|
229 |
~pp_open_box:pp_open_vbox0 |
|
230 |
~pp_epilogue:pp_print_cut |
|
231 |
(fun fmt idx _ -> fprintf fmt "fflush(f_in%i);" (idx + 1))) |
|
232 |
m.mstep.step_inputs |
|
233 |
|
|
234 |
(pp_print_list_i |
|
235 |
~pp_open_box:pp_open_vbox0 |
|
236 |
(fun fmt idx _ -> fprintf fmt "fflush(f_out%i);" (idx + 1))) |
|
237 |
m.mstep.step_outputs |
|
238 |
|
|
239 |
(pp_print_list_i2 |
|
240 |
~pp_open_box:pp_open_vbox0 |
|
241 |
~pp_epilogue:pp_print_cut |
|
242 |
print_get_input) |
|
243 |
(m.mname.node_inputs, m.mstep.step_inputs) |
|
244 |
|
|
245 |
(fun fmt () -> |
|
246 |
pp_main_call mname main_mem fmt m input_values m.mstep.step_outputs) () |
|
247 |
|
|
248 |
(pp_print_list_i2 |
|
249 |
~pp_open_box:pp_open_vbox0 |
|
250 |
~pp_prologue:pp_print_cut |
|
251 |
print_put_output) |
|
252 |
(m.mname.node_outputs, m.mstep.step_outputs) |
|
253 |
|
|
254 |
let print_usage fmt () = |
|
255 |
fprintf fmt |
|
256 |
"@[<v 2>\ |
|
257 |
void usage(char *argv[]) {@,\ |
|
258 |
printf(\"Usage: %%s\\n\", argv[0]);@,\ |
|
259 |
printf(\" -t: produce trace files for input/output flows\\n\");@,\ |
|
260 |
printf(\" -d<dir>: directory containing traces (default: _traces)\\n\");@,\ |
|
261 |
printf(\" -p<prefix>: prefix_simu.scope<id> (default: file_node)\\n\");@,\ |
|
262 |
exit (8);@]@,\ |
|
263 |
}" |
|
264 |
|
|
265 |
let print_options fmt name = |
|
266 |
fprintf fmt |
|
267 |
"@[<v>int traces = 0;@,\ |
|
268 |
char* prefix = \"%s\";@,\ |
|
269 |
char* dir = \".\";@,\ |
|
270 |
@[<v 2>while ((argc > 1) && (argv[1][0] == '-')) {@,\ |
|
271 |
@[<v 2>switch (argv[1][1]) {@,\ |
|
272 |
@[<v 2>case 't':@,\ |
|
273 |
traces = 1;@,\ |
|
274 |
break;@,\ |
|
275 |
@]@,\ |
|
276 |
@[<v 2>case 'd':@,\ |
|
277 |
dir = &argv[1][2];@,\ |
|
278 |
break;@,\ |
|
279 |
@]@,\ |
|
280 |
@[<v 2>case 'p':@,\ |
|
281 |
prefix = &argv[1][2];@,\ |
|
282 |
break;@,\ |
|
283 |
@]@,\ |
|
284 |
@[<v 2>default:@,\ |
|
285 |
printf(\"Wrong Argument: %%s\\n\", argv[1]);@,\ |
|
286 |
usage(argv);@]@]@,\ |
|
287 |
}@,\ |
|
288 |
++argv;@,\ |
|
289 |
--argc;@]@,\ |
|
290 |
}@]" |
|
291 |
name |
|
292 |
|
|
293 |
let print_main_code fmt (basename, m) = |
|
294 |
let mname = m.mname.node_id in |
|
295 |
(* TODO: find a proper way to shorthen long names. This causes segfault in the binary when trying to fprintf in them *) |
|
296 |
let mname = if String.length mname > 50 |
|
297 |
then string_of_int (Hashtbl.hash mname) else mname in |
|
298 |
let main_mem = |
|
299 |
if !Options.static_mem && !Options.main_node <> "" |
|
300 |
then "&main_mem" |
|
301 |
else "main_mem" in |
|
302 |
|
|
303 |
fprintf fmt |
|
304 |
"@[<v>\ |
|
305 |
%a@,\ |
|
306 |
@,\ |
|
307 |
@[<v 2>int main (int argc, char *argv[]) {@,\ |
|
308 |
%a@,\ |
|
309 |
@,\ |
|
310 |
%a@,\ |
|
311 |
%a@,\ |
|
312 |
%a@,\ |
|
313 |
%a@,\ |
|
314 |
%a@,\ |
|
315 |
%a@]@,\ |
|
316 |
}@,\ |
|
317 |
%areturn 1;@]@,}@]@." |
|
318 |
|
|
319 |
print_usage () |
|
320 |
|
|
321 |
print_options (basename ^ "_" ^ mname) |
|
322 |
|
|
323 |
print_main_inout_declaration m |
|
324 |
|
|
325 |
(Plugins.c_backend_main_loop_body_prefix basename mname) () |
|
326 |
|
|
327 |
(print_main_memory_allocation mname main_mem) m |
|
328 |
|
|
329 |
(fun fmt () -> |
|
330 |
if !Options.mpfr then |
|
331 |
fprintf fmt "@[<v>%a@,%a@]@," |
|
332 |
print_global_initialize basename |
|
333 |
(print_main_initialize mname main_mem) m) () |
|
334 |
|
|
335 |
(print_main_loop mname main_mem) m |
|
336 |
|
|
337 |
Plugins.c_backend_main_loop_body_suffix () |
|
338 |
|
|
339 |
(fun fmt () -> |
|
340 |
if !Options.mpfr then |
|
341 |
fprintf fmt "@[<v>%a@,%a@]@," |
|
342 |
(print_main_clear mname main_mem) m |
|
343 |
print_global_clear basename) () |
|
344 |
|
|
345 |
let print_main_header fmt () = |
|
346 |
fprintf fmt |
|
347 |
"@[<v>#include <stdio.h>@,\ |
|
348 |
#include <unistd.h>@,\ |
|
349 |
%a@]" |
|
350 |
(fun fmt () -> fprintf fmt |
|
351 |
(if !Options.cpp then |
|
352 |
"#include \"%s/io_frontend.hpp\"" |
|
353 |
else |
|
354 |
"#include <string.h>@,\ |
|
355 |
#include \"%s/io_frontend.h\"") |
|
356 |
(Options_management.core_dependency "io_frontend")) () |
|
357 |
|
|
358 |
let print_main_c main_fmt main_machine basename _prog _machines _dependencies = |
|
359 |
fprintf main_fmt |
|
360 |
"@[<v>\ |
|
361 |
%a@,\ |
|
362 |
#include <stdlib.h>@,\ |
|
363 |
#include <assert.h>@,\ |
|
364 |
%a@,\ |
|
365 |
@,\ |
|
366 |
%a@,\ |
|
367 |
%a |
|
368 |
@]@." |
|
369 |
print_main_header () |
|
370 |
print_import_alloc_prototype |
|
371 |
{ |
|
372 |
local = true; |
|
373 |
name = basename; |
|
374 |
content = []; |
|
375 |
is_stateful = true (* assuming it is stateful*) |
|
376 |
} |
|
377 |
|
|
378 |
(* Print the svn version number and the supported C standard (C90 or C99) *) |
|
379 |
pp_print_version () |
|
380 |
|
|
381 |
print_main_code (basename, main_machine) |
|
382 |
|
|
383 |
end |
|
218 | 384 |
|
219 | 385 |
(* Local Variables: *) |
220 | 386 |
(* compile-command:"make -C ../../.." *) |
Also available in: Unified diff
some rewriting in C backend pretty-printer