Skip to content

Commit 8c4c46e

Browse files
committed
Add STL typecheck support for XOR expressions
Adds support for the X, XN, X( and XN( instructions.
1 parent c71d73c commit 8c4c46e

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
@@ -368,15 +368,23 @@ class statement_list_typecheckt : public typecheckt
368368
const codet &op_code,
369369
const symbolt &tia_element);
370370

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

378-
/// Performs a typecheck on a STL boolean Or instruction. Reads and modifies
379-
/// the RLO, OR and FC bit.
378+
/// Performs a typecheck on a STL boolean XOR instruction. Reads and
379+
/// modifies the RLO, OR and FC bit.
380+
/// \param op_code: OP code of the instruction.
381+
/// \param tia_element: Symbol representation of the TIA element.
382+
void typecheck_statement_list_xor(
383+
const codet &op_code,
384+
const symbolt &tia_element);
385+
386+
/// Performs a typecheck on a STL boolean And Not instruction. Reads and
387+
/// modifies the RLO, OR and FC bit.
380388
/// \param op_code: OP code of the instruction.
381389
/// \param tia_element: Symbol representation of the TIA element.
382390
void typecheck_statement_list_and_not(
@@ -391,6 +399,14 @@ class statement_list_typecheckt : public typecheckt
391399
const codet &op_code,
392400
const symbolt &tia_element);
393401

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

424+
/// Performs a typecheck on a nested XOR instruction. Pushes the current
425+
/// program state to the nesting stack and cleans the RLO, OR and FC bit.
426+
/// \param op_code: OP code of the instruction.
427+
void typecheck_statement_list_nested_xor(const codet &op_code);
428+
408429
/// Performs a typecheck on a nested And Not instruction. Pushes the current
409430
/// program state to the nesting stack and cleans the RLO, OR and FC bit.
410431
/// \param op_code: OP code of the instruction.
@@ -415,6 +436,11 @@ class statement_list_typecheckt : public typecheckt
415436
/// \param op_code: OP code of the instruction.
416437
void typecheck_statement_list_nested_or_not(const codet &op_code);
417438

439+
/// Performs a typecheck on a nested XOR Not instruction. Pushes the current
440+
/// program state to the nesting stack and cleans the RLO, OR and FC bit.
441+
/// \param op_code: OP code of the instruction.
442+
void typecheck_statement_list_nested_xor_not(const codet &op_code);
443+
418444
/// Performs a typecheck on a Nesting Closed instruction. Uses the latest
419445
/// entry on the nesting stack and modifies the RLO, OR and FC bit according
420446
/// to the instruction that started the nesting.
@@ -478,19 +504,40 @@ class statement_list_typecheckt : public typecheckt
478504
/// Performs a typecheck on a STL instruction with an additional operand that
479505
/// should be no constant.
480506
/// \param op_code: OP code of the instruction.
481-
/// \return Reference to the operand.
507+
/// \return: Reference to the operand.
482508
const symbol_exprt &
483509
typecheck_instruction_with_non_const_operand(const codet &op_code);
484510

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

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

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

0 commit comments

Comments
 (0)