Skip to content

Commit 74fb770

Browse files
committed
[clang][Interp] Implement bitXor opcode
Differential Revision: https://reviews.llvm.org/D136956
1 parent 6d965c9 commit 74fb770

File tree

5 files changed

+42
-0
lines changed

5 files changed

+42
-0
lines changed

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,8 @@ bool ByteCodeExprGen<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) {
241241
return Discard(this->emitShl(*LT, *RT, BO));
242242
case BO_Shr:
243243
return Discard(this->emitShr(*LT, *RT, BO));
244+
case BO_Xor:
245+
return Discard(this->emitBitXor(*T, BO));
244246
case BO_LAnd:
245247
case BO_LOr:
246248
default:

clang/lib/AST/Interp/Integral.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,11 @@ template <unsigned Bits, bool Signed> class Integral final {
227227
return false;
228228
}
229229

230+
static bool bitXor(Integral A, Integral B, unsigned OpBits, Integral *R) {
231+
*R = Integral(A.V ^ B.V);
232+
return false;
233+
}
234+
230235
static bool neg(Integral A, Integral *R) {
231236
*R = -A;
232237
return false;

clang/lib/AST/Interp/Interp.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,23 @@ bool BitOr(InterpState &S, CodePtr OpPC) {
211211
return false;
212212
}
213213

214+
/// 1) Pops the RHS from the stack.
215+
/// 2) Pops the LHS from the stack.
216+
/// 3) Pushes 'LHS ^ RHS' on the stack
217+
template <PrimType Name, class T = typename PrimConv<Name>::T>
218+
bool BitXor(InterpState &S, CodePtr OpPC) {
219+
const T &RHS = S.Stk.pop<T>();
220+
const T &LHS = S.Stk.pop<T>();
221+
222+
unsigned Bits = RHS.bitWidth();
223+
T Result;
224+
if (!T::bitXor(LHS, RHS, Bits, &Result)) {
225+
S.Stk.push<T>(Result);
226+
return true;
227+
}
228+
return false;
229+
}
230+
214231
/// 1) Pops the RHS from the stack.
215232
/// 2) Pops the LHS from the stack.
216233
/// 3) Pushes 'LHS % RHS' on the stack (the remainder of dividing LHS by RHS).

clang/lib/AST/Interp/Opcodes.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ def Div : Opcode {
419419
let Types = [NumberTypeClass];
420420
let HasGroup = 1;
421421
}
422+
def BitXor : IntegerOpcode;
422423

423424
//===----------------------------------------------------------------------===//
424425
// Unary operators.

clang/test/AST/Interp/literals.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,23 @@ namespace bitOr {
279279
static_assert((12 | true) == 13, "");
280280
};
281281

282+
namespace bitXor {
283+
#pragma clang diagnostic push
284+
#pragma clang diagnostic ignored "-Wxor-used-as-pow"
285+
static_assert((10 ^ 1) == 11, "");
286+
static_assert((10 ^ 10) == 0, "");
287+
288+
enum {
289+
ONE = 1,
290+
};
291+
292+
static_assert((1337 ^ -1) == -1338, "");
293+
static_assert((0 | gimme(12)) == 12, "");
294+
static_assert((12 ^ true) == 13, "");
295+
static_assert((12 ^ ONE) == 13, "");
296+
#pragma clang diagnostic pop
297+
};
298+
282299
#if __cplusplus >= 201402L
283300
constexpr bool IgnoredUnary() {
284301
bool bo = true;

0 commit comments

Comments
 (0)