@@ -160,6 +160,49 @@ inline bitor_exprt &to_bitor_expr(exprt &expr)
160160 return static_cast <bitor_exprt &>(expr);
161161}
162162
163+ // / \brief Bit-wise NOR
164+ // / When given one operand, this is equivalent to the bit-wise negation.
165+ // / When given three or more operands, this is equivalent to the bit-wise
166+ // / negation of the bitand expression with the same operands.
167+ class bitnor_exprt : public multi_ary_exprt
168+ {
169+ public:
170+ bitnor_exprt (exprt _op0, exprt _op1)
171+ : multi_ary_exprt(std::move(_op0), ID_bitnor, std::move(_op1))
172+ {
173+ }
174+
175+ bitnor_exprt (exprt::operandst _operands, typet _type)
176+ : multi_ary_exprt(ID_bitnor, std::move(_operands), std::move(_type))
177+ {
178+ }
179+ };
180+
181+ template <>
182+ inline bool can_cast_expr<bitnor_exprt>(const exprt &base)
183+ {
184+ return base.id () == ID_bitnor;
185+ }
186+
187+ // / \brief Cast an exprt to a \ref bitnor_exprt
188+ // /
189+ // / \a expr must be known to be \ref bitnor_exprt.
190+ // /
191+ // / \param expr: Source expression
192+ // / \return Object of type \ref bitnor_exprt
193+ inline const bitnor_exprt &to_bitnor_expr (const exprt &expr)
194+ {
195+ PRECONDITION (expr.id () == ID_bitnor);
196+ return static_cast <const bitnor_exprt &>(expr);
197+ }
198+
199+ // / \copydoc to_bitnor_expr(const exprt &)
200+ inline bitnor_exprt &to_bitnor_expr (exprt &expr)
201+ {
202+ PRECONDITION (expr.id () == ID_bitnor);
203+ return static_cast <bitnor_exprt &>(expr);
204+ }
205+
163206// / \brief Bit-wise XOR
164207class bitxor_exprt : public multi_ary_exprt
165208{
@@ -201,13 +244,21 @@ inline bitxor_exprt &to_bitxor_expr(exprt &expr)
201244}
202245
203246// / \brief Bit-wise XNOR
247+ // / When given one operand, this is equivalent to the bit-wise negation.
248+ // / When given three or more operands, this is equivalent to the bit-wise
249+ // / negation of the bitxor expression with the same operands.
204250class bitxnor_exprt : public multi_ary_exprt
205251{
206252public:
207253 bitxnor_exprt (exprt _op0, exprt _op1)
208254 : multi_ary_exprt(std::move(_op0), ID_bitxnor, std::move(_op1))
209255 {
210256 }
257+
258+ bitxnor_exprt (exprt::operandst _operands, typet _type)
259+ : multi_ary_exprt(ID_bitxnor, std::move(_operands), std::move(_type))
260+ {
261+ }
211262};
212263
213264template <>
@@ -275,6 +326,49 @@ inline bitand_exprt &to_bitand_expr(exprt &expr)
275326 return static_cast <bitand_exprt &>(expr);
276327}
277328
329+ // / \brief Bit-wise NAND
330+ // / When given one operand, this is equivalent to the bit-wise negation.
331+ // / When given three or more operands, this is equivalent to the bit-wise
332+ // / negation of the bitand expression with the same operands.
333+ class bitnand_exprt : public multi_ary_exprt
334+ {
335+ public:
336+ bitnand_exprt (exprt _op0, exprt _op1)
337+ : multi_ary_exprt(std::move(_op0), ID_bitnand, std::move(_op1))
338+ {
339+ }
340+
341+ bitnand_exprt (exprt::operandst _operands, typet _type)
342+ : multi_ary_exprt(ID_bitnand, std::move(_operands), std::move(_type))
343+ {
344+ }
345+ };
346+
347+ template <>
348+ inline bool can_cast_expr<bitnand_exprt>(const exprt &base)
349+ {
350+ return base.id () == ID_bitnand;
351+ }
352+
353+ // / \brief Cast an exprt to a \ref bitnand_exprt
354+ // /
355+ // / \a expr must be known to be \ref bitnand_exprt.
356+ // /
357+ // / \param expr: Source expression
358+ // / \return Object of type \ref bitnand_exprt
359+ inline const bitnand_exprt &to_bitnand_expr (const exprt &expr)
360+ {
361+ PRECONDITION (expr.id () == ID_bitnand);
362+ return static_cast <const bitnand_exprt &>(expr);
363+ }
364+
365+ // / \copydoc to_bitnand_expr(const exprt &)
366+ inline bitnand_exprt &to_bitnand_expr (exprt &expr)
367+ {
368+ PRECONDITION (expr.id () == ID_bitnand);
369+ return static_cast <bitnand_exprt &>(expr);
370+ }
371+
278372// / \brief A base class for shift and rotate operators
279373class shift_exprt : public binary_exprt
280374{
0 commit comments