[PATCH] RISC-V: Move UNSPEC_SSP_SET and UNSPEC_SSP_TEST to correct enum
[gcc.git] / gcc / crc-verification.cc
blobc7b0fedd6e4d8bcc8b90398761d06525bfb10fa6
1 /* Execute symbolically all paths of the loop.
2 Calculate the value of the polynomial by executing loop with real values to
3 create LFSR state.
4 After each iteration check that final states of calculated CRC values match
5 determined LFSR.
6 Copyright (C) 2022-2025 Free Software Foundation, Inc.
7 Contributed by Mariam Arutunian <mariamarutunian@gmail.com>
9 This file is part of GCC.
11 GCC is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 3, or (at your option) any later
14 version.
16 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 for more details.
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING3. If not see
23 <http://www.gnu.org/licenses/>. */
25 #include "crc-verification.h"
26 #include "config.h"
27 #include "system.h"
28 #include "coretypes.h"
29 #include "backend.h"
30 #include "tree.h"
31 #include "gimple.h"
32 #include "ssa.h"
33 #include "gimple-iterator.h"
34 #include "tree-cfg.h"
35 #include "cfganal.h"
36 #include "tree-ssa-loop.h"
38 /* Check whether defined variable is used outside the loop, only
39 CRC's definition is allowed to be used outside the loop. */
41 bool
42 crc_symbolic_execution::is_used_outside_the_loop (tree def)
44 imm_use_iterator imm_iter;
45 gimple *use_stmt;
46 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
48 if (!flow_bb_inside_loop_p (m_crc_loop, use_stmt->bb))
50 if (is_a<gphi *> (use_stmt)
51 && as_a<gphi *> (use_stmt) == m_output_crc)
52 return false;
53 if (dump_file)
54 fprintf (dump_file, "Defined variable is used outside the loop.\n");
55 return true;
58 return false;
61 /* Calculate value of the rhs operation of GS assigment statement
62 and assign it to lhs variable. */
64 bool
65 crc_symbolic_execution::execute_assign_statement (const gassign *gs)
67 enum tree_code rhs_code = gimple_assign_rhs_code (gs);
68 tree lhs = gimple_assign_lhs (gs);
69 if (dump_file && (dump_flags & TDF_DETAILS))
70 fprintf (dump_file, "lhs type : %s \n",
71 get_tree_code_name (TREE_CODE (lhs)));
73 /* This will filter some normal cases too. Ex. usage of array. */
74 if (TREE_CODE (lhs) != SSA_NAME)
75 return false;
77 /* Check uses only when m_output_crc is known. */
78 if (m_output_crc)
79 if (is_used_outside_the_loop (lhs))
80 return false;
82 if (gimple_num_ops (gs) != 2 && gimple_num_ops (gs) != 3)
84 if (dump_file)
85 fprintf (dump_file,
86 "Warning, encountered unsupported operation, "
87 "with %s code while executing assign statement!\n",
88 get_tree_code_name (rhs_code));
89 return false;
92 tree op1 = gimple_assign_rhs1 (gs);
93 tree op2 = nullptr;
95 if (gimple_num_ops (gs) == 3)
96 op2 = gimple_assign_rhs2 (gs);
98 state *current_state = m_states.last ();
99 return current_state->do_operation (rhs_code, op1, op2, lhs);
102 /* Add E edge into the STACK if it doesn't have an immediate
103 successor edge going to the loop header.
105 When loop counter is checked in the if condition,
106 we mustn't continue on real path as we want to stop the execution before
107 the second iteration. */
109 bool
110 crc_symbolic_execution::add_edge (edge e, auto_vec<edge> &stack)
112 if (EDGE_COUNT (e->dest->succs) == 0)
113 return false;
115 edge next_bb_edge = EDGE_SUCC (e->dest, 0);
116 if (next_bb_edge && next_bb_edge->dest == m_crc_loop->header)
118 if (dump_file && (dump_flags & TDF_DETAILS))
119 fprintf (dump_file, "Completed one iteration. "
120 "Won't iterate loop once more, yet.\n");
122 return keep_states ();
124 else
126 if (dump_file && (dump_flags & TDF_DETAILS))
127 fprintf (dump_file, "Adding the edge into the stack.\n");
129 /* If the result of the condition is true/false,
130 continue execution only by the true/false branch. */
131 stack.quick_push (e);
133 return true;
136 /* Add next basic blocks of the conditional block COND_BB
137 for the execution path into the STACK.
138 If the condition depends on symbolic values, keep both edges.
139 If the condition is true, keep true edge, else - false edge.
140 Returns true if addition succeeds. Otherwise - false. */
142 bool
143 crc_symbolic_execution::add_next_bbs (basic_block cond_bb,
144 state *new_branch_state,
145 auto_vec<edge> &stack)
147 edge true_edge;
148 edge false_edge;
149 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
151 /* When the condition depends on symbolic values. */
152 if (new_branch_state->get_last_cond_status () == CS_SYM)
154 /* Supported CRC cases may have only two states. */
155 if (m_states.length () == 2)
157 if (dump_file && (dump_flags & TDF_DETAILS))
158 fprintf (dump_file, "Going to add a new state, "
159 "but there's already two states.\n");
160 return false;
162 /* Add true branch's state into the states.
163 False branch's state will be kept in the current state. */
164 m_states.quick_push (new_branch_state);
166 if (dump_file && (dump_flags & TDF_DETAILS))
167 fprintf (dump_file, "Adding true and false edges into the stack.\n");
169 /* Add outgoing edges to the stack. */
170 stack.quick_push (false_edge);
171 stack.quick_push (true_edge);
173 return true;
175 /* When the condition evaluates to true. */
176 else if (new_branch_state->get_last_cond_status () == CS_TRUE)
178 if (dump_file && (dump_flags & TDF_DETAILS))
179 fprintf (dump_file, "Condition is true.\n");
180 add_edge (true_edge, stack);
182 /* When the condition evaluates to false. */
183 else if (new_branch_state->get_last_cond_status () == CS_FALSE)
185 if (dump_file && (dump_flags & TDF_DETAILS))
186 fprintf (dump_file, "Condition is false.\n");
187 add_edge (false_edge, stack);
189 else
191 if (dump_file && (dump_flags & TDF_DETAILS))
192 fprintf (dump_file, "Something went wrong "
193 "during handling conditional statement.\n");
194 return false;
197 /* When we continue execution of only one path,
198 there's no need of new state. */
199 delete new_branch_state;
200 return true;
203 /* Add conditions depending on symbolic variables in the states.
205 Keep conditions of each branch execution in its state.
207 if (a == 0) // a's value is unknown
209 new_branch_state.keep (a==0)
210 current_state.keep (a!=0)
212 The condition is kept in the bit level.
213 For ex.
214 If a's size is 8 and its value is {symb_a, 0, 0, 0, 0, 0, 0, 0},
215 then for a == 0 we'll have symb_a == 0 condition. */
217 bool
218 crc_symbolic_execution::add_condition (const gcond *cond,
219 state *current_state,
220 state *new_branch_state)
222 tree lhs = gimple_cond_lhs (cond);
223 tree rhs = gimple_cond_rhs (cond);
224 switch (gimple_cond_code (cond))
226 case EQ_EXPR:
228 new_branch_state->add_equal_cond (lhs, rhs);
229 if (new_branch_state->get_last_cond_status () == CS_SYM)
230 current_state->add_not_equal_cond (lhs, rhs);
231 return true;
233 case NE_EXPR:
235 new_branch_state->add_not_equal_cond (lhs, rhs);
236 if (new_branch_state->get_last_cond_status () == CS_SYM)
237 current_state->add_equal_cond (lhs, rhs);
238 return true;
240 case GT_EXPR:
242 new_branch_state->add_greater_than_cond (lhs, rhs);
243 if (new_branch_state->get_last_cond_status () == CS_SYM)
244 current_state->add_less_or_equal_cond (lhs, rhs);
245 return true;
247 case LT_EXPR:
249 new_branch_state->add_less_than_cond (lhs, rhs);
250 if (new_branch_state->get_last_cond_status () == CS_SYM)
251 current_state->add_greater_or_equal_cond (lhs, rhs);
252 return true;
254 case GE_EXPR:
256 new_branch_state->add_greater_or_equal_cond (lhs, rhs);
257 if (new_branch_state->get_last_cond_status () == CS_SYM)
258 current_state->add_less_than_cond (lhs, rhs);
259 return true;
261 case LE_EXPR:
263 new_branch_state->add_less_or_equal_cond (lhs, rhs);
264 if (new_branch_state->get_last_cond_status () == CS_SYM)
265 current_state->add_greater_than_cond (lhs, rhs);
266 return true;
268 default:
270 if (dump_file && (dump_flags & TDF_DETAILS))
271 fprintf (dump_file, "Unsupported condition.\n");
272 return false;
277 /* Create new states for true and false branches.
278 Keep conditions in new created states. */
280 bool
281 crc_symbolic_execution::resolve_condition (const gcond *cond,
282 auto_vec<edge> &stack)
284 state *current_state = m_states.last ();
285 state *new_branch_state = new state (*current_state);
287 /* Create new states and for true and false branches keep corresponding
288 conditions. */
289 if (!add_condition (cond, current_state, new_branch_state))
290 return false;
292 /* Add true and false edges to the stack. */
293 return add_next_bbs (cond->bb, new_branch_state, stack);
296 /* If final states are less than two, add new FINAL_STATE and return true.
297 Otherwise, return false.
298 Supported CRC cases may not have more than two final states. */
299 bool crc_symbolic_execution::add_final_state (state *final_state)
301 if (m_final_states.length () < 2)
302 m_final_states.quick_push (final_state);
303 else
305 if (dump_file)
306 fprintf (dump_file,
307 "There are already two final states\n");
308 return false;
310 return true;
313 /* Keep the state of the executed path in final states. */
315 bool crc_symbolic_execution::keep_states ()
317 if (m_states.is_empty ())
318 return false;
320 if (!add_final_state (m_states.last ()))
322 if (dump_file && (dump_flags & TDF_DETAILS))
323 fprintf (dump_file, "Couldn't add final state.\n");
324 return false;
327 m_states.pop ();
328 return true;
331 /* Execute gimple statements of BB.
332 Keeping values of variables in the state. */
334 bool
335 crc_symbolic_execution::execute_bb_gimple_statements (basic_block bb,
336 auto_vec<edge> &stack)
338 for (gimple_stmt_iterator bsi = gsi_start_bb (bb);
339 !gsi_end_p (bsi); gsi_next (&bsi))
341 gimple *gs = gsi_stmt (bsi);
342 if (dump_file && (dump_flags & TDF_DETAILS))
344 fprintf (dump_file, "Executing ");
345 print_gimple_stmt (dump_file, gs, dump_flags);
347 switch (gimple_code (gs))
349 case GIMPLE_ASSIGN:
351 if (!execute_assign_statement (as_a<const gassign *> (gs)))
352 return false;
353 break;
355 case GIMPLE_COND:
357 return resolve_condition (as_a<const gcond *> (gs), stack);
359 /* Just skip debug statements. */
360 case GIMPLE_DEBUG:
361 break;
362 default:
364 if (dump_file)
365 fprintf (dump_file,
366 "Warning, encountered unsupported statement, "
367 "while executing gimple statements!\n");
368 return false;
373 /* Add each outgoing edge of the current block to the stack,
374 despite the edges going to the loop header.
375 This code isn't reachable if the last statement of the basic block
376 is a conditional statement or return statement.
377 Those cases are handled separately.
378 We mustn't encounter edges going to the CRC loop header. */
380 edge out_edge;
381 edge_iterator ei;
382 FOR_EACH_EDGE (out_edge, ei, bb->succs)
383 if (out_edge->dest != m_crc_loop->header)
384 stack.quick_push (out_edge);
385 else
386 return false;
388 return true;
391 /* Assign values of phi instruction to its result.
392 Keep updated values in the state. */
394 bool
395 crc_symbolic_execution::execute_bb_phi_statements (basic_block bb,
396 edge incoming_edge)
398 for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
399 gsi_next (&gsi))
401 gphi *phi = gsi.phi ();
402 tree lhs = gimple_phi_result (phi);
404 /* Check uses only when m_output_crc is known. */
405 if (m_output_crc)
406 if (is_used_outside_the_loop (lhs))
407 return false;
409 /* Don't consider virtual operands. */
410 if (virtual_operand_p (lhs))
411 continue;
413 if (dump_file && (dump_flags & TDF_DETAILS))
415 fprintf (dump_file, "Determining the value "
416 "for the following phi.\n");
417 print_gimple_stmt (dump_file, phi, dump_flags);
420 tree rhs = PHI_ARG_DEF_FROM_EDGE (phi, incoming_edge);
422 state *current_state = m_states.last ();
423 if (!current_state->do_operation (VAR_DECL, rhs, nullptr, lhs))
424 return false;
426 return true;
429 /* Execute all statements of BB.
430 Keeping values of variables in the state. */
432 bool
433 crc_symbolic_execution::execute_bb_statements (basic_block bb,
434 edge incoming_edge,
435 auto_vec<edge> &stack)
437 if (!execute_bb_phi_statements (bb, incoming_edge))
438 return false;
440 return execute_bb_gimple_statements (bb, stack);
443 /* If the phi statements' result variables have initial constant value in the
444 beginning of the loop, initialize those variables. */
446 void
447 assign_known_vals_to_header_phis (state *state, class loop *crc_loop)
449 basic_block bb = crc_loop->header;
450 for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
451 gsi_next (&gsi))
454 gphi *phi = gsi.phi ();
455 tree lhs = gimple_phi_result (phi);
457 /* Don't consider virtual operands. */
458 if (virtual_operand_p (lhs))
459 continue;
461 tree inital_val = PHI_ARG_DEF_FROM_EDGE (phi,
462 loop_preheader_edge (crc_loop));
463 if (TREE_CODE (inital_val) == INTEGER_CST)
465 if (dump_file && (dump_flags & TDF_DETAILS))
467 fprintf (dump_file, "First value of phi is a constant, "
468 "assigning the number to ");
469 print_generic_expr (dump_file, lhs, dump_flags);
470 fprintf (dump_file, " variable.\n");
472 state->do_operation (VAR_DECL, inital_val,
473 nullptr, lhs);
478 /* If the phi statements' result variables have initial constant value in the
479 beginning of the loop, initialize those variables with
480 the value calculated during the previous iteration. */
482 bool
483 assign_calc_vals_to_header_phis (const vec<state *> &prev_states,
484 state *curr_state,
485 class loop *crc_loop)
487 basic_block bb = crc_loop->header;
488 for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
489 gsi_next (&gsi))
491 gphi *phi = gsi.phi ();
492 tree lhs = gimple_phi_result (phi);
494 /* Don't consider virtual operands. */
495 if (virtual_operand_p (lhs))
496 continue;
497 tree inital_val = PHI_ARG_DEF_FROM_EDGE (phi,
498 loop_preheader_edge (crc_loop));
499 if (TREE_CODE (inital_val) == INTEGER_CST)
501 tree input_tree = PHI_ARG_DEF_FROM_EDGE (phi,
502 loop_latch_edge (crc_loop));
503 value * val_st1 = prev_states[0]->get_value (input_tree),
504 *val_st2 = prev_states[1]->get_value (input_tree);
505 if (!state::is_bit_vector (val_st1)
506 || !state::is_bit_vector (val_st2))
508 if (dump_file && (dump_flags & TDF_DETAILS))
510 fprintf (dump_file, "The calculated values of ");
511 print_generic_expr (dump_file, input_tree, dump_flags);
512 fprintf (dump_file, " variable is not constant.\n");
514 return false;
516 else if (!state::check_const_value_equality (val_st1, val_st2))
518 if (dump_file && (dump_flags & TDF_DETAILS))
520 fprintf (dump_file, "The calculated values of ");
521 print_generic_expr (dump_file, input_tree, dump_flags);
522 fprintf (dump_file, " variable is different in the previous "
523 "iteration paths.\n");
525 return false;
527 else
529 if (dump_file && (dump_flags & TDF_DETAILS))
531 fprintf (dump_file, "Assigning calculated number to ");
532 print_generic_expr (dump_file, lhs, dump_flags);
533 fprintf (dump_file, " variable.\n");
535 unsigned HOST_WIDE_INT calc_number
536 = state::make_number (val_st1);
537 tree calc_num_tree = build_int_cstu (TREE_TYPE (lhs),
538 calc_number);
539 curr_state->do_operation (VAR_DECL, calc_num_tree, nullptr, lhs);
543 return true;
546 /* Create initial state of the CRC_LOOP's header BB variables which have
547 constant values.
548 If it is the first iteration of the loop, initialise variables with the
549 initial values, otherwise initialise the variable with the value calculated
550 during the previous execution. */
552 state *
553 crc_symbolic_execution::create_initial_state (class loop *crc_loop)
555 state *curr_state = new state;
556 if (!m_final_states.is_empty ())
558 if (!assign_calc_vals_to_header_phis (m_final_states, curr_state,
559 crc_loop))
560 return nullptr;
561 state::remove_states (&m_final_states);
563 else
564 assign_known_vals_to_header_phis (curr_state, crc_loop);
565 return curr_state;
568 /* Symbolically execute the CRC loop, doing one iteration. */
570 bool
571 crc_symbolic_execution::symb_execute_crc_loop ()
573 if (dump_file && (dump_flags & TDF_DETAILS))
574 fprintf (dump_file, "\n\nExecuting the loop with symbolic values.\n\n");
576 state *curr_state = create_initial_state (m_crc_loop);
577 if (!curr_state)
578 return false;
580 m_states.quick_push (curr_state);
582 auto_vec<edge> stack (m_crc_loop->num_nodes);
584 basic_block header_bb = m_crc_loop->header;
585 if (!execute_bb_gimple_statements (header_bb, stack))
586 return false;
588 /* Successor BB's are added into the stack
589 from the execute_bb_gimple_statements function. */
590 while (!stack.is_empty ())
592 /* Look at the edge on the top of the stack. */
593 edge e = stack.last ();
594 stack.pop ();
596 /* Get destination block of the edge. */
597 basic_block dest_bb = e->dest;
599 /* Execute only basic blocks of the m_crc_loop.
600 At the end of the execution path save states in final states. */
601 if (!flow_bb_inside_loop_p (m_crc_loop, dest_bb))
603 m_is_last_iteration = true;
604 if (!keep_states ())
605 return false;
606 continue;
609 /* Execute statements. */
610 if (!execute_bb_statements (dest_bb, e, stack))
611 return false;
613 return true;
616 /* Determine which bit of the DATA must be 1.
617 We assume that last bit must be 1. */
619 unsigned HOST_WIDE_INT
620 determine_index (tree data, bool is_shift_left)
622 if (is_shift_left)
623 /* This won't work correctly in the case when data's size is larger,
624 but MSB is checked for the middle bit. */
625 return tree_to_uhwi (TYPE_SIZE (TREE_TYPE (data))) - 1;
626 return 0;
629 /* Assign appropriate values to data, CRC
630 and other phi results to calculate the polynomial. */
632 void
633 assign_vals_to_header_phis (state *polynomial_state, class loop *crc_loop,
634 gphi *crc_phi, gphi *data_phi,
635 bool is_shift_left)
637 basic_block bb = crc_loop->header;
638 for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
639 gsi_next (&gsi))
642 gphi *phi = gsi.phi ();
643 tree lhs = gimple_phi_result (phi);
645 /* Don't consider virtual operands. */
646 if (virtual_operand_p (lhs))
647 continue;
649 if ((data_phi && phi == data_phi) || (!data_phi && phi == crc_phi))
651 if (dump_file && (dump_flags & TDF_DETAILS))
653 fprintf (dump_file, "Assigning the required value to ");
654 print_generic_expr (dump_file, lhs, dump_flags);
655 fprintf (dump_file, " variable.\n");
657 polynomial_state->do_assign_pow2 (lhs,
658 determine_index (lhs,
659 is_shift_left));
661 else if (phi == crc_phi)
663 if (dump_file && (dump_flags & TDF_DETAILS))
665 fprintf (dump_file, "Assigning 0 value to ");
666 print_generic_expr (dump_file, lhs, dump_flags);
667 fprintf (dump_file, " variable.\n");
669 polynomial_state->do_operation (VAR_DECL,
670 build_zero_cst (TREE_TYPE (lhs)),
671 nullptr, lhs);
673 else
675 edge loop_preheader = loop_preheader_edge (crc_loop);
676 tree inital_val = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader);
677 if (TREE_CODE (inital_val) == INTEGER_CST)
679 if (dump_file && (dump_flags & TDF_DETAILS))
681 fprintf (dump_file, "First value of phi is a constant, "
682 "assigning the number to ");
683 print_generic_expr (dump_file, lhs, dump_flags);
684 fprintf (dump_file, " variable.\n");
686 polynomial_state->do_operation (VAR_DECL, inital_val,
687 nullptr, lhs);
689 else
691 if (dump_file && (dump_flags & TDF_DETAILS))
693 fprintf (dump_file, "First value of phi isn't constant, "
694 "assigning to ");
695 print_generic_expr (dump_file, lhs, dump_flags);
696 fprintf (dump_file, " variable.\n");
698 polynomial_state->do_operation (VAR_DECL,
699 build_zero_cst (TREE_TYPE (lhs)),
700 nullptr, lhs);
706 /* Execute the loop, which calculates CRC with initial values,
707 to calculate the polynomial. */
709 bool
710 crc_symbolic_execution::execute_crc_loop (gphi *crc_phi,
711 gphi *data_phi,
712 bool is_shift_left)
714 if (dump_file && (dump_flags & TDF_DETAILS))
715 fprintf (dump_file, "\n\nTrying to calculate the polynomial.\n\n");
717 m_states.quick_push (new state);
719 basic_block bb = m_crc_loop->header;
720 assign_vals_to_header_phis (m_states.last (), m_crc_loop, crc_phi, data_phi,
721 is_shift_left);
723 auto_vec<edge> stack (m_crc_loop->num_nodes);
725 if (!execute_bb_gimple_statements (bb, stack))
726 return false;
728 /* stack may not be empty. Successor BB's are added into the stack
729 from the execute_bb_gimple_statements function. */
730 while (!stack.is_empty ())
732 /* Look at the edge on the top of the stack. */
733 edge e = stack.last ();
734 stack.pop ();
736 /* Get dest block of the edge. */
737 basic_block bb = e->dest;
739 /* Execute only basic blocks of the m_crc_loop. */
740 if (!flow_bb_inside_loop_p (m_crc_loop, bb))
741 continue;
743 /* Execute statements. */
744 if (!execute_bb_statements (bb, e, stack))
745 return false;
748 if (m_final_states.length () != 1)
750 if (dump_file && (dump_flags & TDF_DETAILS))
751 fprintf (dump_file, "The number of states is not one when executed "
752 "the loop for calculating the polynomial.\n");
753 return false;
755 return true;
758 /* Return true if all bits of the POLYNOMIAL are constants (0 or 1).
759 Otherwise return false. */
761 bool
762 polynomial_is_known (const value *polynomial)
764 for (size_t i = 0; i < polynomial->length (); i++)
766 if (!is_a<bit *> ((*polynomial)[i]))
767 return false;
769 return true;
772 /* Execute the loop, which is expected to calculate CRC,
773 to extract polynomial, assigning real numbers to CRC and data.
774 Returns a pair, first value of the pair is the tree containing
775 the value of the polynomial, second is the calculated polynomial.
776 The pair may contain nullptr. */
778 std::pair <tree, value *>
779 crc_symbolic_execution::extract_polynomial (gphi *crc_phi, gphi *data_phi,
780 tree calculated_crc,
781 bool is_shift_left)
783 if (!execute_crc_loop (crc_phi, data_phi, is_shift_left))
784 return std::make_pair (nullptr, nullptr);
786 if (m_final_states.length () != 1)
788 if (dump_file && (dump_flags & TDF_DETAILS))
789 fprintf (dump_file, "The number of states isn't one "
790 "after executing the loop.\n");
791 return std::make_pair (nullptr, nullptr);
793 state *polynomial_state = m_final_states.last ();
795 /* CALCULATED_CRC contains the value of the polynomial
796 after one iteration of the loop. */
797 if (dump_file && (dump_flags & TDF_DETAILS))
799 fprintf (dump_file, "Getting the value of ");
800 print_generic_expr (dump_file, calculated_crc, dump_flags);
801 fprintf (dump_file, " variable.\n");
804 /* Get the value (bit vector) of the tree (it may be the polynomial). */
805 value *polynomial = polynomial_state->get_value (calculated_crc);
806 if (!polynomial)
808 if (dump_file && (dump_flags & TDF_DETAILS))
809 fprintf (dump_file, "Polynomial's value is null.\n");
810 return std::make_pair (nullptr, nullptr);
813 if (dump_file && (dump_flags & TDF_DETAILS))
815 /* Note: It may not be the real polynomial.
816 If it's a bit reflected CRC,
817 then to get a real polynomial,
818 it must be reflected and 1 bit added. */
819 fprintf (dump_file, "Polynomial's value is ");
820 state::print_value (polynomial);
823 /* Check that polynomial's all bits are constants. */
824 if (!polynomial_is_known (polynomial))
826 if (dump_file && (dump_flags & TDF_DETAILS))
827 fprintf (dump_file, "Polynomial's value is not constant.\n");
828 return std::make_pair (nullptr, nullptr);
831 return std::make_pair (calculated_crc, polynomial);
835 /**************************** LFSR MATCHING *********************************/
838 /* Return true if CONST_BIT value equals to 1.
839 Otherwise, return false. */
841 bool
842 is_one (value_bit *const_bit)
844 return is_a<bit *> (const_bit)
845 && (as_a<bit *> (const_bit))->get_val () == 1;
848 /* Return true if BIT is symbolic,
849 its index is same as LFSR bit's index (LFSR_BIT_INDEX)
850 and the origin is same as CRC_ORIGIN. */
852 bool
853 is_a_valid_symb (value_bit *bit, tree crc_origin, size_t lfsr_bit_index)
855 if (!is_a<symbolic_bit *> (bit))
856 return false;
858 symbolic_bit *sym_bit = as_a<symbolic_bit *> (bit);
859 bool is_correct_index = (sym_bit->get_index () == lfsr_bit_index);
860 bool is_same_crc_origin = (sym_bit->get_origin () == crc_origin);
861 return is_correct_index && is_same_crc_origin;
864 /* Return true if the BIT is a valid crc[LFSR_BIT_INDEX] ^ 1,
865 where i is a whole number and left part's origin is same as CRC_ORIGIN.
866 LFSR_BIT_INDEX is the index of the LFSR bit from the same position as in CRC.
868 If there is lfsr[8] at LFSR value vectors' 9-th bit,
869 when in the CRC vectors' 9-th bit's value must be
870 crc[8].
872 Otherwise, return false. */
874 bool
875 is_a_valid_xor_one (value_bit *bit, tree crc_origin, size_t lfsr_bit_index)
877 if (is_a<bit_xor_expression *> (bit))
879 bit_xor_expression *xor_exp = as_a<bit_xor_expression *> (bit);
880 if (is_one (xor_exp->get_right ()))
881 return is_a_valid_symb (xor_exp->get_left (), crc_origin,
882 lfsr_bit_index);
883 return false;
885 return false;
888 /* Return true, if CONDITION_EXP checks CRC's MSB/LSB value
889 (under which xor is/not done).
890 Otherwise, return false. */
892 bool
893 may_be_xors_condition (tree crc_origin, value_bit *condition_exp,
894 size_t sb_index)
896 if (!crc_origin)
897 return false;
899 if (!condition_exp)
900 return false;
902 /* The CONDITION_EXP of CRC may be a symbolic bit, if CRC is xor-ed with
903 the data, and updated CRC's significant bit is checked.
904 So, the CONDITION_EXP will be CRC's condition if it's origin is the same as
905 CRC_ORIGIN, and it's index equals to checked significant bit's index. */
906 if (is_a<symbolic_bit *> (condition_exp))
908 symbolic_bit *condition_symbolic = as_a<symbolic_bit *> (condition_exp);
909 return crc_origin == condition_symbolic->get_origin ()
910 && sb_index == condition_symbolic->get_index ();
912 /* The CONDITION_EXP of CRC may be a bit_xor_expression,
913 if CRC and data are xor-ed only for significant bit's check.
914 I.e. CONDITION_EXP in this case may be crc[]^data[].
915 So, the CONDITION_EXP will be CRC's condition if it's left or right
916 part's origin is the same as CRC_ORIGIN, and it's index equals to checked
917 significant bit's index. */
918 else if (is_a<bit_xor_expression *> (condition_exp))
920 bit_xor_expression *condition_xor_exp = as_a<bit_xor_expression *>
921 (condition_exp);
922 if (!(is_a<symbolic_bit *> (condition_xor_exp->get_left ())
923 && is_a<symbolic_bit *> (condition_xor_exp->get_right ())))
924 return false;
926 symbolic_bit *cond_left
927 = as_a<symbolic_bit *> (condition_xor_exp->get_left ());
928 symbolic_bit *cond_right
929 = as_a<symbolic_bit *> (condition_xor_exp->get_right ());
930 bool cond_left_is_crc = (crc_origin == cond_left->get_origin ()
931 && sb_index == cond_left->get_index ());
932 bool cond_right_is_crc = (crc_origin == cond_right->get_origin ()
933 && sb_index == cond_right->get_index ());
934 return cond_left_is_crc || cond_right_is_crc;
936 return false;
939 /* Check whether the condition is checked for significant bit being 0 or 1.
940 If IS_ONE is 1, when check whether the significant bit is 1 (xor branch),
941 if 0, whether the significant bit is 0 (not xor branch). */
943 bool
944 is_crc_xor_condition (tree crc_origin, unsigned char is_one,
945 size_t sb_index, state *final_state)
947 /* The CRC cases we detect must contain only one condition related to CRC. */
948 if (final_state->get_conditions ().elements () != 1)
949 return false;
951 auto condition_iter = final_state->get_conditions ().begin ();
952 if (!is_a<bit_condition *> (*condition_iter))
953 return false;
955 /* If the condition is for checking MSB/LSB, then
956 if is_one is 1 and the condition is for checking MSB/LSB being one, or
957 if is_one is 0 and condition is for checking MSB/LSB being 0
958 return true, otherwise - false. */
959 value_bit *cond_exp = (*condition_iter)->get_left ();
960 if (may_be_xors_condition (crc_origin, cond_exp, sb_index))
962 if (!is_a<bit *> ((*condition_iter)->get_right ()))
963 return false;
965 bit_condition *condition = as_a<bit_condition *> (*condition_iter);
966 unsigned char comparison_val
967 = as_a<bit *> ((*condition_iter)->get_right ())->get_val ();
968 if (condition->get_code () == EQ_EXPR)
969 return comparison_val == is_one;
970 if (condition->get_code () == NE_EXPR)
971 return comparison_val != is_one;
972 return false;
974 return false;
977 /* Check whether LSB/MSB of LFSR and calculated (maybe)CRC match.
978 If MSB is checked in the CRC loop, then here we check LSB, or vice versa.
979 CHECKED_SB_VALUE indicates which state of CRC value is checked.
980 If the CHECKED_SB_VALUE is 1 - then xor-ed CRC value is checked,
981 otherwise, not xor-ed is checked. */
983 bool
984 given_sb_match (value_bit *crc, value_bit *lfsr,
985 unsigned short checked_sb_value)
987 /* If LFSR's MSB/LSB value is a constant (0 or 1),
988 then CRC's MSB/LSB must have the same value. */
989 if (is_a<bit *> (lfsr))
991 if (!((is_a<bit *> (crc)
992 && as_a<bit *> (crc)->get_val ()
993 == as_a<bit *> (lfsr)->get_val ())))
994 return false;
995 return true;
997 /* If LFSR's MSB/LSB value is a symbolic_bit
998 (that means MSB/LSB of the polynomial is 1),
999 then CRC's MSB/LSB must be equal to CHECKED_SB_VALUE. */
1000 else if (is_a<symbolic_bit *> (lfsr))
1002 if (!(is_a<bit *> (crc)
1003 && (as_a<bit *> (crc)->get_val () == checked_sb_value)))
1004 return false;
1005 return true;
1007 return false;
1010 /* Check whether significant bit of LFSR and calculated (maybe)CRC match. */
1012 bool
1013 sb_match (const value *lfsr, const value *crc_value, size_t sb_index,
1014 size_t it_end, unsigned short value)
1016 /* If it's bit-forward CRC, check 0 bit's value. */
1017 if (sb_index == it_end - 1)
1019 if (dump_file && (dump_flags & TDF_DETAILS))
1020 fprintf (dump_file, "Checking 0 bit.\n");
1022 if (!given_sb_match ((*crc_value)[0], (*lfsr)[0], value))
1023 return false;
1025 /* If it's bit-reversed CRC, check last bit's value. */
1026 else if (sb_index == 0)
1028 if (dump_file && (dump_flags & TDF_DETAILS))
1029 fprintf (dump_file, "Checking %zu bit.\n", it_end);
1031 if (!given_sb_match ((*crc_value)[it_end], (*lfsr)[it_end], value))
1032 return false;
1034 else
1036 if (dump_file && (dump_flags & TDF_DETAILS))
1037 fprintf (dump_file, "Significant bit index is incorrect.\n");
1039 return true;
1042 /* Match the CRC to the LFSR, where CRC's all bit values are
1043 symbolic_bit or symbolic_bit ^ 1, besides MSB/LSB (it may be constant). */
1045 bool
1046 lfsr_and_crc_bits_match (const value *lfsr, const value *crc_state,
1047 tree crc_origin, size_t i, size_t it_end,
1048 size_t sb_index, unsigned short checked_sb_value)
1051 /* Check whether significant bits of LFSR and CRC match. */
1052 if (!sb_match (lfsr, crc_state, sb_index, it_end, checked_sb_value))
1053 return false;
1055 for (; i < it_end; i++)
1057 if (dump_file && (dump_flags & TDF_DETAILS))
1058 fprintf (dump_file, "Checking %zu bit.\n", i);
1060 /* Check the case when in lfsr we have LFSR (i)^LFSR (SBi),
1061 where 0<i<LFSR_size and SBi is the index of MSB/LSB (LFSR_size-1/0).
1062 In that case in crc_state (resulting CRC)
1063 we must have crc (i) ^ 1 case, when condition is true
1064 and crc (i) when condition is false,
1065 (as CRC is xor-ed with the polynomial only if the LSB/MSB is one)
1066 where k is a whole number. */
1067 if (is_a<bit_xor_expression *> ((*lfsr)[i]))
1069 size_t index = (as_a<bit_xor_expression *> ((*lfsr)[i]))->get_left ()
1070 ->get_index ();
1071 /* Check CRC value of xor branch. */
1072 if (checked_sb_value == 1)
1074 if (!(is_a_valid_xor_one ((*crc_state)[i], crc_origin, index)))
1075 return false;
1077 else /* Check CRC value of not xor branch. */
1079 if (!(is_a_valid_symb ((*crc_state)[i], crc_origin, index)))
1080 return false;
1083 /* Check the case when in LFSR we have LFSR (i), where 0<i<LFSR_size.
1084 In that case in resulting CRC we must have crc (i) case,
1085 when condition is true or condition is false.
1086 If we have just LFSR (i), that means polynomial's i ± 1 bit is 0,
1087 so despite CRC is xor-ed or not, we will have crc (i). */
1088 else if (is_a<symbolic_bit *> ((*lfsr)[i]))
1090 size_t index = (as_a<symbolic_bit *> ((*lfsr)[i]))->get_index ();
1091 if (!(is_a_valid_symb ((*crc_state)[i], crc_origin, index)))
1092 return false;
1094 else
1096 if (dump_file && (dump_flags & TDF_DETAILS))
1097 fprintf (dump_file, "Not expected expression in LFSR.\n");
1098 return false;
1101 return true;
1104 /* Return origin of CRC_BIT.
1105 The first tree in loop, from which CRC's calculation is started. */
1107 tree
1108 get_origin_of_crc_from_symb_bit (value_bit *crc_bit)
1110 if (is_a<symbolic_bit *> (crc_bit))
1111 return as_a<symbolic_bit *> (crc_bit)->get_origin ();
1112 return nullptr;
1115 /* Return origin of CRC_BIT. The first tree in loop, from which CRC's
1116 calculation is started. If the CRC_BIT is symbolic value, return its origin,
1117 otherwise return its left part's origin (right must be 1 if its CRC's
1118 value). */
1120 tree
1121 get_origin_of_crc (value_bit *crc_bit)
1123 tree origin = get_origin_of_crc_from_symb_bit (crc_bit);
1124 if (origin)
1125 return origin;
1126 else if (is_a<bit_xor_expression *> (crc_bit))
1128 value_bit *crc_bit_left
1129 = as_a<bit_xor_expression *> (crc_bit)->get_left ();
1130 return get_origin_of_crc_from_symb_bit (crc_bit_left);
1132 return nullptr;
1135 /* Determine and initialize significant bit index
1136 (if MSB is checked for CRC, then it's LSB index, and vice versa)
1137 and the remaining part's begin and end.
1138 SB_INDEX is the significant bit index.
1139 IT_BEG is the beginning of the remaining part.
1140 IT_END is the end of the remaining part. */
1142 void
1143 init_sb_index_and_other_part_begin_end (size_t &it_beg, size_t &it_end,
1144 size_t &sb_index, size_t crc_size,
1145 bool is_bit_forward)
1147 it_end = crc_size;
1148 if (is_bit_forward)
1150 sb_index = it_end - 1;
1151 it_beg = 1;
1153 else
1155 it_beg = 0;
1156 sb_index = 0;
1157 --it_end;
1161 /* Return true if CRC_STATE matches the LFSR, otherwise - false.
1162 LFSR - is created LFSR value for the given polynomial and CRC size.
1163 CRC_STATE - contains CRC's calculated value and execution path condition.
1164 IT_BEG and IT_END - are the border indexes of the value to be matched.
1165 SB_INDEX - is the significant bit index of the CRC value,
1166 which will be checked separately.
1167 IF MSB is checked for CRC, when sb_index will be the index of LSB.
1168 Otherwise, will be the index of MSB.
1169 CHECKED_SB_VALUE - is the significant bit's value (used for CRC's condition).
1170 If CHECKED_SB_VALUE is 1, it indicates that CRC_STATE is
1171 xor-ed path's state.
1172 If CHECKED_SB_VALUE is 0, then CRC_STATE is the state of the
1173 not xor branch. */
1175 bool
1176 lfsr_matches_crc_state (const value *lfsr, state *crc_state, value *crc_value,
1177 size_t it_beg, size_t it_end, size_t sb_index,
1178 unsigned short checked_sb_value)
1180 if (dump_file && (dump_flags & TDF_DETAILS))
1182 fprintf (dump_file, "Starting to match the following CRC value: ");
1183 state::print_value (crc_value);
1186 /* Get the origin (name) of the calculated CRC value.
1187 All bits must have the same origin. */
1188 tree crc_origin = get_origin_of_crc ((*crc_value)[it_beg]);
1189 if (!crc_origin)
1190 return false;
1192 if (!is_crc_xor_condition (crc_origin, checked_sb_value, sb_index, crc_state))
1193 return false;
1195 /* Check whether CRC_VALUE and LFSR bits match. */
1196 return lfsr_and_crc_bits_match (lfsr, crc_value, crc_origin,
1197 it_beg, it_end, sb_index, checked_sb_value);
1200 /* Return true if in the CRC_VALUE exists xor expression.
1201 Otherwise, return false. */
1203 bool
1204 is_xor_state (value *crc_value, size_t it_beg, size_t it_end)
1206 for (unsigned j = it_beg; j < it_end; ++j)
1207 if ((*crc_value)[j]->get_type () == BIT_XOR_EXPRESSION)
1208 return true;
1209 return false;
1212 /* Keep the value of calculated CRC. */
1214 value *
1215 get_crc_val (tree calculated_crc, state *curr_state)
1217 if (!calculated_crc)
1219 if (dump_file && (dump_flags & TDF_DETAILS))
1220 fprintf (dump_file, "Couldn't get the potential CRC variable.\n");
1221 return nullptr;
1224 /* When the calculated CRC is constant, it's not possible to determine
1225 whether the CRC has been calculated. */
1226 if (TREE_CODE (calculated_crc) == INTEGER_CST)
1228 if (dump_file && (dump_flags & TDF_DETAILS))
1229 fprintf (dump_file, "Calculated CRC is a constant.\n");
1230 return nullptr;
1233 /* Get calculated return value. */
1234 value * crc_value = curr_state->get_value (calculated_crc);
1236 if (!crc_value)
1238 if (dump_file && (dump_flags & TDF_DETAILS))
1239 fprintf (dump_file, "CRC is not in the state.\n");
1240 return nullptr;
1242 return crc_value;
1245 /* Return true if all states from the FINAL_STATES match the LFSR,
1246 otherwise - false. */
1248 bool
1249 all_states_match_lfsr (value *lfsr, bool is_bit_forward, tree calculated_crc,
1250 const vec<state *> &final_states)
1252 if (final_states.length () != 2)
1254 if (dump_file && (dump_flags & TDF_DETAILS))
1255 fprintf (dump_file, "The final states count isn't two.\n");
1256 return false;
1259 value *crc_xor_value = get_crc_val (calculated_crc, final_states[0]);
1260 value *crc_not_xor_value = get_crc_val (calculated_crc, final_states[1]);
1262 /* LFSR's size must be equal to CRC's size. */
1263 if ((crc_xor_value->length () != lfsr->length ())
1264 || (crc_not_xor_value->length () != lfsr->length ()))
1265 return false;
1267 /* Depending on whether it is bit-forward or reversed CRC,
1268 determine in which significant bit new value is added,
1269 to examine that bit separately.
1270 If in the CRC algorithm MSB (sb_index) is checked to be one for xor,
1271 then here we check LSB separately (marginal bit).
1272 If LSB (sb_index) is checked, then we separate MSB (marginal bit). */
1273 size_t it_beg, it_end, sb_index;
1274 init_sb_index_and_other_part_begin_end (it_beg, it_end, sb_index,
1275 crc_xor_value->length (),
1276 is_bit_forward);
1278 size_t xor_st_index = 0, not_xor_st_index = 1;
1279 /* If first is not xor's state,
1280 then the second state is assumed to be xor's state. */
1281 if (!is_xor_state (crc_xor_value, it_beg, it_end))
1283 std::swap (crc_xor_value, crc_not_xor_value);
1284 xor_st_index = 1;
1285 not_xor_st_index = 0;
1288 /* If xor-ed CRC value doesn't match the LFSR value, return false. */
1289 if (!lfsr_matches_crc_state (lfsr, final_states[xor_st_index], crc_xor_value,
1290 it_beg, it_end, sb_index, 1))
1291 return false;
1293 /* If not xor-ed CRC value doesn't match the LFSR value, return false. */
1294 if (!lfsr_matches_crc_state (lfsr, final_states[not_xor_st_index],
1295 crc_not_xor_value, it_beg, it_end, sb_index, 0))
1296 return false;
1298 return true;