Skip to content

Commit 201dbdc

Browse files
committed
Add STL typecheck support for XOR expressions
Adds support for the X, XN, X( and XN( instructions.
1 parent 0ad55a4 commit 201dbdc

File tree

2 files changed

+175
-55
lines changed

2 files changed

+175
-55
lines changed

src/statement-list/statement_list_typecheck.cpp

Lines changed: 123 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,10 @@ void statement_list_typecheckt::typecheck_statement_list_instruction(
378378
typecheck_statement_list_or(op_code, tia_element);
379379
else if(ID_statement_list_or_not == statement)
380380
typecheck_statement_list_or_not(op_code, tia_element);
381+
else if(ID_statement_list_xor == statement)
382+
typecheck_statement_list_xor(op_code, tia_element);
383+
else if(ID_statement_list_xor_not == statement)
384+
typecheck_statement_list_xor_not(op_code, tia_element);
381385
else if(ID_statement_list_and_nested == statement)
382386
typecheck_statement_list_nested_and(op_code);
383387
else if(ID_statement_list_and_not_nested == statement)
@@ -386,6 +390,10 @@ void statement_list_typecheckt::typecheck_statement_list_instruction(
386390
typecheck_statement_list_nested_or(op_code);
387391
else if(ID_statement_list_or_not_nested == statement)
388392
typecheck_statement_list_nested_or_not(op_code);
393+
else if(ID_statement_list_xor_nested == statement)
394+
typecheck_statement_list_nested_xor(op_code);
395+
else if(ID_statement_list_xor_not_nested == statement)
396+
typecheck_statement_list_nested_xor_not(op_code);
389397
else if(ID_statement_list_nesting_closed == statement)
390398
typecheck_statement_list_nesting_closed(op_code);
391399
else if(ID_statement_list_assign == statement)
@@ -732,9 +740,8 @@ void statement_list_typecheckt::typecheck_statement_list_and(
732740
const codet &op_code,
733741
const symbolt &tia_element)
734742
{
735-
const symbol_exprt &sym{
736-
typecheck_instruction_with_non_const_operand(op_code)};
737-
const exprt op{typecheck_identifier(tia_element, sym.get_identifier())};
743+
exprt op{
744+
typecheck_simple_boolean_instruction_operand(op_code, tia_element, false)};
738745

739746
// If inside of a bit string and if the OR bit is not set, create an 'and'
740747
// expression with the operand and the current contents of the rlo bit. If
@@ -755,24 +762,22 @@ void statement_list_typecheckt::typecheck_statement_list_and_not(
755762
const codet &op_code,
756763
const symbolt &tia_element)
757764
{
758-
const symbol_exprt &sym{
759-
typecheck_instruction_with_non_const_operand(op_code)};
760-
const exprt op{typecheck_identifier(tia_element, sym.get_identifier())};
761-
const not_exprt not_op{op};
765+
exprt op{
766+
typecheck_simple_boolean_instruction_operand(op_code, tia_element, true)};
762767

763768
// If inside of a bit string and if the OR bit is not set, create an 'and'
764769
// expression with the operand and the current contents of the rlo bit. If
765770
// the OR bit is set then this instruction is part of an 'and-before-or'
766771
// block and needs to be added to the rlo in a special way.
767772
if(or_bit && fc_bit)
768-
add_to_or_rlo_wrapper(not_op);
773+
add_to_or_rlo_wrapper(op);
769774
else if(fc_bit)
770775
{
771-
const and_exprt unsimplified{rlo_bit, not_op};
776+
const and_exprt unsimplified{rlo_bit, op};
772777
rlo_bit = simplify_expr(unsimplified, namespacet(symbol_table));
773778
}
774779
else
775-
initialize_bit_expression(not_op);
780+
initialize_bit_expression(op);
776781
}
777782

778783
void statement_list_typecheckt::typecheck_statement_list_or(
@@ -821,6 +826,47 @@ void statement_list_typecheckt::typecheck_statement_list_or_not(
821826
initialize_bit_expression(not_op);
822827
}
823828

829+
void statement_list_typecheckt::typecheck_statement_list_xor(
830+
const codet &op_code,
831+
const symbolt &tia_element)
832+
{
833+
const symbol_exprt &sym{
834+
typecheck_instruction_with_non_const_operand(op_code)};
835+
const exprt op{typecheck_identifier(tia_element, sym.get_identifier())};
836+
837+
// If inside of a bit string, create an 'xor' expression with the operand and
838+
// the current contents of the rlo bit.
839+
if(fc_bit)
840+
{
841+
const xor_exprt unsimplified{rlo_bit, op};
842+
rlo_bit = simplify_expr(unsimplified, namespacet(symbol_table));
843+
or_bit = false;
844+
}
845+
else
846+
initialize_bit_expression(op);
847+
}
848+
849+
void statement_list_typecheckt::typecheck_statement_list_xor_not(
850+
const codet &op_code,
851+
const symbolt &tia_element)
852+
{
853+
const symbol_exprt &sym{
854+
typecheck_instruction_with_non_const_operand(op_code)};
855+
const exprt op{typecheck_identifier(tia_element, sym.get_identifier())};
856+
const not_exprt not_op{op};
857+
858+
// If inside of a bit string, create an 'xor not' expression with the
859+
// operand and the current contents of the rlo bit.
860+
if(fc_bit)
861+
{
862+
const xor_exprt unsimplified{rlo_bit, not_op};
863+
rlo_bit = simplify_expr(unsimplified, namespacet(symbol_table));
864+
or_bit = false;
865+
}
866+
else
867+
initialize_bit_expression(not_op);
868+
}
869+
824870
void statement_list_typecheckt::typecheck_statement_list_and_before_or()
825871
{
826872
if(fc_bit)
@@ -835,61 +881,49 @@ void statement_list_typecheckt::typecheck_statement_list_and_before_or()
835881
void statement_list_typecheckt::typecheck_statement_list_nested_and(
836882
const codet &op_code)
837883
{
838-
typecheck_instruction_without_operand(op_code);
839-
// If inside of a bit string use the value of the rlo. If this is the first
840-
// expression of a bit string, load the value of the nested operation by
841-
// implicitly setting the rlo to true.
842-
if(!fc_bit)
843-
rlo_bit = true_exprt{};
844-
const nesting_stack_entryt stack_entry{rlo_bit, or_bit, op_code};
845-
nesting_stack.push_back(stack_entry);
846-
fc_bit = false;
847-
or_bit = false;
884+
// Set the rlo to true implicitly so that the value of the AND instruction
885+
// is being loaded in case of a new bit string.
886+
typecheck_nested_boolean_instruction(op_code, true_exprt{});
848887
}
849888

850889
void statement_list_typecheckt::typecheck_statement_list_nested_and_not(
851890
const codet &op_code)
852891
{
853-
typecheck_instruction_without_operand(op_code);
854-
// If inside of a bit string use the value of the rlo. If this is the first
855-
// expression of a bit string, load the value of the nested operation by
856-
// implicitly setting the rlo to true.
857-
if(!fc_bit)
858-
rlo_bit = true_exprt{};
859-
const nesting_stack_entryt stack_entry{rlo_bit, or_bit, op_code};
860-
nesting_stack.push_back(stack_entry);
861-
fc_bit = false;
862-
or_bit = false;
892+
// Set the rlo to true implicitly so that the value of the AND instruction
893+
// is being loaded in case of a new bit string.
894+
typecheck_nested_boolean_instruction(op_code, true_exprt{});
863895
}
864896

865897
void statement_list_typecheckt::typecheck_statement_list_nested_or(
866898
const codet &op_code)
867899
{
868-
typecheck_instruction_without_operand(op_code);
869-
// If inside of a bit string use the value of the rlo. If this is the first
870-
// expression of a bit string, load the value of the nested operation by
871-
// implicitly setting the rlo to false.
872-
if(!fc_bit)
873-
rlo_bit = false_exprt{};
874-
const nesting_stack_entryt stack_entry{rlo_bit, or_bit, op_code};
875-
nesting_stack.push_back(stack_entry);
876-
fc_bit = false;
877-
or_bit = false;
900+
// Set the rlo to false implicitly so that the value of the OR instruction
901+
// is being loaded in case of a new bit string.
902+
typecheck_nested_boolean_instruction(op_code, false_exprt{});
878903
}
879904

880905
void statement_list_typecheckt::typecheck_statement_list_nested_or_not(
881906
const codet &op_code)
882907
{
883-
typecheck_instruction_without_operand(op_code);
884-
// If inside of a bit string use the value of the rlo. If this is the first
885-
// expression of a bit string, load the value of the nested operation by
886-
// implicitly setting the rlo to false.
887-
if(!fc_bit)
888-
rlo_bit = false_exprt{};
889-
const nesting_stack_entryt stack_entry{rlo_bit, or_bit, op_code};
890-
nesting_stack.push_back(stack_entry);
891-
fc_bit = false;
892-
or_bit = false;
908+
// Set the rlo to false implicitly so that the value of the OR instruction
909+
// is being loaded in case of a new bit string.
910+
typecheck_nested_boolean_instruction(op_code, false_exprt{});
911+
}
912+
913+
void statement_list_typecheckt::typecheck_statement_list_nested_xor(
914+
const codet &op_code)
915+
{
916+
// Set the rlo to false implicitly so that the value of the XOR instruction
917+
// is being loaded in case of a new bit string.
918+
typecheck_nested_boolean_instruction(op_code, false_exprt{});
919+
}
920+
921+
void statement_list_typecheckt::typecheck_statement_list_nested_xor_not(
922+
const codet &op_code)
923+
{
924+
// Set the rlo to false implicitly so that the value of the XOR instruction
925+
// is being loaded in case of a new bit string.
926+
typecheck_nested_boolean_instruction(op_code, false_exprt{});
893927
}
894928

895929
void statement_list_typecheckt::typecheck_statement_list_nesting_closed(
@@ -938,6 +972,17 @@ void statement_list_typecheckt::typecheck_statement_list_nesting_closed(
938972
or_bit = false;
939973
rlo_bit = or_exprt{nesting_stack.back().rlo_bit, not_exprt{rlo_bit}};
940974
}
975+
else if(ID_statement_list_xor_nested == statement)
976+
{
977+
or_bit = false;
978+
rlo_bit = xor_exprt{nesting_stack.back().rlo_bit, rlo_bit};
979+
}
980+
else if(ID_statement_list_xor_not_nested == statement)
981+
{
982+
or_bit = false;
983+
rlo_bit = xor_exprt{nesting_stack.back().rlo_bit, not_exprt{rlo_bit}};
984+
}
985+
nesting_stack.pop_back();
941986
}
942987

943988
void statement_list_typecheckt::typecheck_statement_list_assign(
@@ -1129,6 +1174,34 @@ void statement_list_typecheckt::typecheck_binary_accumulator_instruction(
11291174
}
11301175
}
11311176

1177+
void statement_list_typecheckt::typecheck_nested_boolean_instruction(
1178+
const codet &op_code,
1179+
const exprt &rlo_value)
1180+
{
1181+
typecheck_instruction_without_operand(op_code);
1182+
// If inside of a bit string use the value of the rlo. If this is the first
1183+
// expression of a bit string, load the value of the nested operation by
1184+
// implicitly setting the rlo to the specified value.
1185+
if(!fc_bit)
1186+
rlo_bit = rlo_value;
1187+
const nesting_stack_entryt stack_entry{rlo_bit, or_bit, op_code};
1188+
nesting_stack.push_back(stack_entry);
1189+
fc_bit = false;
1190+
or_bit = false;
1191+
}
1192+
1193+
exprt statement_list_typecheckt::typecheck_simple_boolean_instruction_operand(
1194+
const codet &op_code,
1195+
const symbolt &tia_element,
1196+
bool negate)
1197+
{
1198+
const symbol_exprt &sym{
1199+
typecheck_instruction_with_non_const_operand(op_code)};
1200+
const exprt op{typecheck_identifier(tia_element, sym.get_identifier())};
1201+
const not_exprt not_op{op};
1202+
return negate ? not_op : op;
1203+
}
1204+
11321205
exprt statement_list_typecheckt::typecheck_identifier(
11331206
const symbolt &tia_element,
11341207
const irep_idt &identifier)

src/statement-list/statement_list_typecheck.h

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -370,15 +370,23 @@ class statement_list_typecheckt : public typecheckt
370370
const codet &op_code,
371371
const symbolt &tia_element);
372372

373-
/// Performs a typecheck on a STL boolean And Not instruction. Reads and
373+
/// Performs a typecheck on a STL boolean Or instruction. Reads and
374374
/// modifies the RLO, OR and FC bit.
375375
/// \param op_code: OP code of the instruction.
376376
/// \param tia_element: Symbol representation of the TIA element.
377377
void
378378
typecheck_statement_list_or(const codet &op_code, const symbolt &tia_element);
379379

380-
/// Performs a typecheck on a STL boolean Or instruction. Reads and modifies
381-
/// the RLO, OR and FC bit.
380+
/// Performs a typecheck on a STL boolean XOR instruction. Reads and
381+
/// modifies the RLO, OR and FC bit.
382+
/// \param op_code: OP code of the instruction.
383+
/// \param tia_element: Symbol representation of the TIA element.
384+
void typecheck_statement_list_xor(
385+
const codet &op_code,
386+
const symbolt &tia_element);
387+
388+
/// Performs a typecheck on a STL boolean And Not instruction. Reads and
389+
/// modifies the RLO, OR and FC bit.
382390
/// \param op_code: OP code of the instruction.
383391
/// \param tia_element: Symbol representation of the TIA element.
384392
void typecheck_statement_list_and_not(
@@ -393,6 +401,14 @@ class statement_list_typecheckt : public typecheckt
393401
const codet &op_code,
394402
const symbolt &tia_element);
395403

404+
/// Performs a typecheck on a STL boolean XOR Not instruction. Reads and
405+
/// modifies the RLO, OR and FC bit.
406+
/// \param op_code: OP code of the instruction.
407+
/// \param tia_element: Symbol representation of the TIA element.
408+
void typecheck_statement_list_xor_not(
409+
const codet &op_code,
410+
const symbolt &tia_element);
411+
396412
/// Performs a typecheck on a STL operand-less Or instruction. Reads and
397413
/// modifies the RLO, OR and FC bit.
398414
void typecheck_statement_list_and_before_or();
@@ -407,6 +423,11 @@ class statement_list_typecheckt : public typecheckt
407423
/// \param op_code: OP code of the instruction.
408424
void typecheck_statement_list_nested_or(const codet &op_code);
409425

426+
/// Performs a typecheck on a nested XOR instruction. Pushes the current
427+
/// program state to the nesting stack and cleans the RLO, OR and FC bit.
428+
/// \param op_code: OP code of the instruction.
429+
void typecheck_statement_list_nested_xor(const codet &op_code);
430+
410431
/// Performs a typecheck on a nested And Not instruction. Pushes the current
411432
/// program state to the nesting stack and cleans the RLO, OR and FC bit.
412433
/// \param op_code: OP code of the instruction.
@@ -417,6 +438,11 @@ class statement_list_typecheckt : public typecheckt
417438
/// \param op_code: OP code of the instruction.
418439
void typecheck_statement_list_nested_or_not(const codet &op_code);
419440

441+
/// Performs a typecheck on a nested XOR Not instruction. Pushes the current
442+
/// program state to the nesting stack and cleans the RLO, OR and FC bit.
443+
/// \param op_code: OP code of the instruction.
444+
void typecheck_statement_list_nested_xor_not(const codet &op_code);
445+
420446
/// Performs a typecheck on a Nesting Closed instruction. Uses the latest
421447
/// entry on the nesting stack and modifies the RLO, OR and FC bit according
422448
/// to the instruction that started the nesting.
@@ -480,19 +506,40 @@ class statement_list_typecheckt : public typecheckt
480506
/// Performs a typecheck on a STL instruction with an additional operand that
481507
/// should be no constant.
482508
/// \param op_code: OP code of the instruction.
483-
/// \return Reference to the operand.
509+
/// \return: Reference to the operand.
484510
const symbol_exprt &
485511
typecheck_instruction_with_non_const_operand(const codet &op_code);
486512

487513
/// Performs a typecheck on an operand-less STL instruction.
488514
/// \param op_code: OP code of the instruction.
489515
void typecheck_instruction_without_operand(const codet &op_code);
490516

491-
/// Performs a typecheck on an STL instruction that uses two accumulator
517+
/// Performs a typecheck on a STL instruction that uses two accumulator
492518
/// entries.
493519
/// \param op_code: OP code of the instruction.
494520
void typecheck_binary_accumulator_instruction(const codet &op_code);
495521

522+
/// Performs a typecheck on a STL instruction that initializes a new boolean
523+
/// nesting.
524+
/// \param op_code: OP code of the instruction.
525+
/// \param rlo_value: Value of the RLO that is pushed on the nesting stack
526+
/// for the case that this is the first instruction of a new bit string.
527+
void typecheck_nested_boolean_instruction(
528+
const codet &op_code,
529+
const exprt &rlo_value);
530+
531+
/// Performs a typecheck on the operand of a not nested boolean instruction
532+
/// and returns the result.
533+
/// \param op_code: OP code of the instruction.
534+
/// \param tia_element: Symbol representation of the TIA element.
535+
/// \param negate: Whether the operand should be negated (e.g. for the
536+
/// `AND NOT` expression).
537+
/// \return: Typechecked operand.
538+
exprt typecheck_simple_boolean_instruction_operand(
539+
const codet &op_code,
540+
const symbolt &tia_element,
541+
bool negate);
542+
496543
/// Performs a typecheck on an STL comparison instruction. Modifies the RLO.
497544
/// \param comparison: ID of the compare expression that should be pushed to
498545
/// the RLO.

0 commit comments

Comments
 (0)