@@ -57,8 +57,10 @@ std::map<typet, size_t> slots_per_type(const symbol_tablet &st,
5757#define INSTR_TYPE_SUFFIX " _instructiont"
5858#define VARIABLE_ARRAY_PREFIX CEGIS_PREFIX " variable_array_"
5959#define NUM_PRIMITIVE_OPERANDS 2u
60+ #define NUM_PRIMITIVE_OPCODES 4u
6061#define OPCODE_MEMBER_NAME " opcode"
6162#define OPERAND_ID_MEMBER_NAME_PREFIX " op_"
63+ #define OPERAND_TMP_RESULT_PREFIX " result_op_"
6264#define INSTR_INDEX " i"
6365#define PROGRAM_PARAM_ID " program"
6466#define PROGRAM_SIZE_PARAM_ID " size"
@@ -71,6 +73,12 @@ std::string get_variable_array_name(const symbol_tablet &st, const typet &type)
7173 return result+=type2c (type, namespacet (st));
7274}
7375
76+ symbol_exprt get_variable_array_symbol (const symbol_tablet &st,
77+ const typet &type)
78+ {
79+ return st.lookup (get_variable_array_name (st, type)).symbol_expr ();
80+ }
81+
7482void create_variable_array (symbol_tablet &st, goto_functionst &gf,
7583 const typet &type, const size_t size)
7684{
@@ -127,9 +135,16 @@ bool is_primitive(const typet &type)
127135
128136size_t get_max_operands (const typet &type)
129137{
130- if (is_primitive (type)) return NUM_PRIMITIVE_OPERANDS;
138+ if (! is_primitive (type))
131139 assert (!" Class type operand generation not supported." );
132- return 0 ;
140+ return NUM_PRIMITIVE_OPERANDS;
141+ }
142+
143+ size_t get_num_instructions (const typet &type)
144+ {
145+ if (!is_primitive (type))
146+ assert (!" Class type operand generation not supported." );
147+ return NUM_PRIMITIVE_OPCODES;
133148}
134149
135150size_t get_max_operands (const std::map<typet, size_t > &slots)
@@ -243,7 +258,10 @@ class body_factoryt
243258 symbol_tablet &st;
244259 goto_programt &body;
245260 const std::string &func_name;
261+ const goto_programt::targett end;
246262 goto_programt::targett dummy;
263+ goto_programt::targett last_case;
264+ goto_programt::targett switch_end;
247265public:
248266 goto_programt::targett pos;
249267private:
@@ -258,7 +276,8 @@ class body_factoryt
258276 }
259277public:
260278 body_factoryt (symbol_tablet &st, goto_programt &body, const std::string &name) :
261- st (st), body(body), func_name(name), dummy(body.add_instruction(SKIP))
279+ st (st), body(body), func_name(name), end(body.instructions.end()), dummy(
280+ body.add_instruction(SKIP)), last_case(end), switch_end(end)
262281 {
263282 pos=dummy;
264283 }
@@ -268,15 +287,19 @@ class body_factoryt
268287 body.instructions .erase (dummy);
269288 }
270289
271- void decl (const std::string &name, const exprt &value )
290+ void decl (const std::string &name, const typet &type )
272291 {
273- const typet &type=value.type ();
274292 pos=declare_local_meta_variable (st, func_name, body, pos, name, type);
275- pos=cegis_assign_local_variable (st, body, pos, func_name, name, value);
276293 dead (name);
277294 }
278295
279- void decl (const std::string &name)
296+ void decl (const std::string &name, const exprt &value)
297+ {
298+ decl (name, value.type ());
299+ pos=cegis_assign_local_variable (st, body, pos, func_name, name, value);
300+ }
301+
302+ void decl_instr_member (const std::string &name)
280303 {
281304 const std::string prog (get_local_meta_name (func_name, PROGRAM_PARAM_ID));
282305 const symbol_exprt prog_expr (st.lookup (prog).symbol_expr ());
@@ -315,26 +338,92 @@ class body_factoryt
315338 add_goto (guard, target);
316339 }
317340
318- void add_conditional_instr_goto ()
341+ goto_programt::targett add_conditional_instr_goto (const size_t opcode )
319342 {
343+ const source_locationt loc (default_cegis_source_location ());
344+ if (end == switch_end)
345+ {
346+ switch_end=body.insert_after (pos);
347+ switch_end->type =goto_program_instruction_typet::SKIP;
348+ switch_end->source_location =loc;
349+ }
350+ pos=body.insert_after (pos);
351+ pos->type =goto_program_instruction_typet::GOTO;
352+ pos->source_location =loc;
353+ const constant_exprt rhs (from_integer (opcode, cegis_size_type ()));
354+ const std::string name (get_local_meta_name (func_name, OPCODE_MEMBER_NAME));
355+ const symbol_exprt lhs (st.lookup (name).symbol_expr ());
356+ pos->guard =equal_exprt (lhs, rhs);
357+ if (end != last_case) last_case->targets .push_back (pos);
358+ last_case=pos;
359+ pos=body.insert_after (pos);
360+ pos->type =goto_program_instruction_typet::SKIP;
361+ pos->source_location =loc;
362+ const goto_programt::targett result (pos);
363+ pos=body.insert_after (pos);
364+ pos->type =goto_program_instruction_typet::GOTO;
365+ pos->source_location =loc;
366+ pos->targets .push_back (switch_end);
367+ return result;
368+ }
320369
370+ void finalise_conditional_instr_gotos ()
371+ {
372+ last_case->targets .push_back (switch_end);
373+ last_case=end;
374+ switch_end=end;
321375 }
322376};
323377
378+ std::string get_tmp_op (const symbol_tablet &st, const size_t op,
379+ const typet &type)
380+ {
381+ std::string result (OPERAND_ID_MEMBER_NAME_PREFIX);
382+ result+=std::to_string (op);
383+ result+=' _' ;
384+ return result+=type2c (type, namespacet (st));
385+ }
386+
387+ std::string get_tmp_result_op (const symbol_tablet &st, const typet &type)
388+ {
389+ std::string result (OPERAND_TMP_RESULT_PREFIX);
390+ return result+=type2c (type, namespacet (st));
391+ }
392+
324393void generate_processor_body (symbol_tablet &st, goto_programt &body,
325394 const std::string &name, const std::map<typet, size_t > &slots)
326395{
327396 body_factoryt factory (st, body, name);
328397 factory.decl (INSTR_INDEX, gen_zero (cegis_size_type ()));
329- factory.decl (OPCODE_MEMBER_NAME);
398+ factory.decl_instr_member (OPCODE_MEMBER_NAME);
330399 const goto_programt::targett loop_head=std::prev (factory.pos );
331- for (size_t i=0 ; i < get_max_operands (slots); ++i)
400+ const size_t global_max_operands=get_max_operands (slots);
401+ for (size_t i=0 ; i < global_max_operands; ++i)
332402 {
333403 std::string op_member (OPERAND_ID_MEMBER_NAME_PREFIX);
334- factory.decl (op_member+=std::to_string (i));
404+ factory.decl_instr_member (op_member+=std::to_string (i));
405+ }
406+ for (const std::pair<typet, size_t > &slot : slots)
407+ {
408+ const typet &type=slot.first ;
409+ const size_t max_operands=get_max_operands (type);
410+ for (size_t i=0 ; i < max_operands; ++i)
411+ factory.decl (get_tmp_op (st, i, type), type);
412+ factory.decl (get_tmp_result_op (st, type), type);
413+ }
414+ size_t opcode=0 ;
415+ for (const std::pair<typet, size_t > &slot : slots)
416+ {
417+ // TODO: Declare temp-init per type
418+ const typet &type=slot.first ;
419+ const size_t num_instrs=opcode + get_num_instructions (type);
420+ assert (num_instrs);
421+ goto_programt::targett init;
422+ for (; opcode < num_instrs; ++opcode)
423+ init=factory.add_conditional_instr_goto (opcode);
424+ // TODO: assign value from var array.
335425 }
336- // TODO: Declare temps (lhs, rhs, result) per type
337- // TODO: Declare temp-init per type
426+ factory.finalise_conditional_instr_gotos ();
338427 // TODO: Declare operation per type
339428 // TODO: Declare result assign per type
340429 factory.add_index_increment ();
0 commit comments