Author: Timm Bäder Date: 2022-10-30T09:23:33+01:00 New Revision: 74fb770de9399d7258a8eda974c93610cfde698e
URL: https://github.com/llvm/llvm-project/commit/74fb770de9399d7258a8eda974c93610cfde698e DIFF: https://github.com/llvm/llvm-project/commit/74fb770de9399d7258a8eda974c93610cfde698e.diff LOG: [clang][Interp] Implement bitXor opcode Differential Revision: https://reviews.llvm.org/D136956 Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/Integral.h clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/Opcodes.td clang/test/AST/Interp/literals.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index f13cd7791a6c..516f77cd3d60 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -241,6 +241,8 @@ bool ByteCodeExprGen<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) { return Discard(this->emitShl(*LT, *RT, BO)); case BO_Shr: return Discard(this->emitShr(*LT, *RT, BO)); + case BO_Xor: + return Discard(this->emitBitXor(*T, BO)); case BO_LAnd: case BO_LOr: default: diff --git a/clang/lib/AST/Interp/Integral.h b/clang/lib/AST/Interp/Integral.h index 9ee9fd6d7fd8..8a742333ae57 100644 --- a/clang/lib/AST/Interp/Integral.h +++ b/clang/lib/AST/Interp/Integral.h @@ -227,6 +227,11 @@ template <unsigned Bits, bool Signed> class Integral final { return false; } + static bool bitXor(Integral A, Integral B, unsigned OpBits, Integral *R) { + *R = Integral(A.V ^ B.V); + return false; + } + static bool neg(Integral A, Integral *R) { *R = -A; return false; diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index aacd5209fcfd..23d7b600e1ad 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -211,6 +211,23 @@ bool BitOr(InterpState &S, CodePtr OpPC) { return false; } +/// 1) Pops the RHS from the stack. +/// 2) Pops the LHS from the stack. +/// 3) Pushes 'LHS ^ RHS' on the stack +template <PrimType Name, class T = typename PrimConv<Name>::T> +bool BitXor(InterpState &S, CodePtr OpPC) { + const T &RHS = S.Stk.pop<T>(); + const T &LHS = S.Stk.pop<T>(); + + unsigned Bits = RHS.bitWidth(); + T Result; + if (!T::bitXor(LHS, RHS, Bits, &Result)) { + S.Stk.push<T>(Result); + return true; + } + return false; +} + /// 1) Pops the RHS from the stack. /// 2) Pops the LHS from the stack. /// 3) Pushes 'LHS % RHS' on the stack (the remainder of dividing LHS by RHS). diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td index 73f0f6140f6b..9f938a6440ae 100644 --- a/clang/lib/AST/Interp/Opcodes.td +++ b/clang/lib/AST/Interp/Opcodes.td @@ -419,6 +419,7 @@ def Div : Opcode { let Types = [NumberTypeClass]; let HasGroup = 1; } +def BitXor : IntegerOpcode; //===----------------------------------------------------------------------===// // Unary operators. diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index afb98e3c1ef9..dc99f83fb1df 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -279,6 +279,23 @@ namespace bitOr { static_assert((12 | true) == 13, ""); }; +namespace bitXor { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wxor-used-as-pow" + static_assert((10 ^ 1) == 11, ""); + static_assert((10 ^ 10) == 0, ""); + + enum { + ONE = 1, + }; + + static_assert((1337 ^ -1) == -1338, ""); + static_assert((0 | gimme(12)) == 12, ""); + static_assert((12 ^ true) == 13, ""); + static_assert((12 ^ ONE) == 13, ""); +#pragma clang diagnostic pop +}; + #if __cplusplus >= 201402L constexpr bool IgnoredUnary() { bool bo = true; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits