Skip to content

Commit f4b4062

Browse files
committed
ASR,C,LLVM: Support UnsignedIntegerBitNot
1 parent e642072 commit f4b4062

File tree

4 files changed

+31
-1
lines changed

4 files changed

+31
-1
lines changed

src/libasr/ASR.asdl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ expr
250250
| IntegerBinOp(expr left, binop op, expr right, ttype type, expr? value)
251251
| UnsignedIntegerConstant(int n, ttype type)
252252
| UnsignedIntegerUnaryMinus(expr arg, ttype type, expr? value)
253+
| UnsignedIntegerBitNot(expr arg, ttype type, expr? value)
253254
| UnsignedIntegerCompare(expr left, cmpop op, expr right, ttype type, expr? value)
254255
| UnsignedIntegerBinOp(expr left, binop op, expr right, ttype type, expr? value)
255256
| RealConstant(float r, ttype type)

src/libasr/codegen/asr_to_c_cpp.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2036,7 +2036,8 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) {
20362036
}
20372037
}
20382038

2039-
void visit_IntegerBitNot(const ASR::IntegerBitNot_t& x) {
2039+
template<typename T>
2040+
void handle_SU_IntegerBitNot(const T& x) {
20402041
CHECK_FAST_C_CPP(compiler_options, x)
20412042
self().visit_expr(*x.m_arg);
20422043
int expr_precedence = last_expr_precedence;
@@ -2048,6 +2049,14 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) {
20482049
}
20492050
}
20502051

2052+
void visit_IntegerBitNot(const ASR::IntegerBitNot_t& x) {
2053+
handle_SU_IntegerBitNot(x);
2054+
}
2055+
2056+
void visit_UnsignedIntegerBitNot(const ASR::UnsignedIntegerBitNot_t& x) {
2057+
handle_SU_IntegerBitNot(x);
2058+
}
2059+
20512060
void visit_IntegerUnaryMinus(const ASR::IntegerUnaryMinus_t &x) {
20522061
handle_UnaryMinus(x);
20532062
}

src/libasr/codegen/asr_to_llvm.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6193,6 +6193,15 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
61936193
tmp = builder->CreateNot(tmp);
61946194
}
61956195

6196+
void visit_UnsignedIntegerBitNot(const ASR::UnsignedIntegerBitNot_t &x) {
6197+
if (x.m_value) {
6198+
this->visit_expr_wrapper(x.m_value, true);
6199+
return;
6200+
}
6201+
this->visit_expr_wrapper(x.m_arg, true);
6202+
tmp = builder->CreateNot(tmp);
6203+
}
6204+
61966205
void visit_IntegerUnaryMinus(const ASR::IntegerUnaryMinus_t &x) {
61976206
if (x.m_value) {
61986207
this->visit_expr_wrapper(x.m_value, true);

src/lpython/semantics/python_ast_to_asr.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3410,6 +3410,17 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
34103410
tmp = ASR::make_IntegerBitNot_t(al, x.base.base.loc, operand, dest_type, value);
34113411
return;
34123412
}
3413+
else if (ASRUtils::is_unsigned_integer(*operand_type)) {
3414+
if (ASRUtils::expr_value(operand) != nullptr) {
3415+
int64_t op_value = ASR::down_cast<ASR::UnsignedIntegerConstant_t>(
3416+
ASRUtils::expr_value(operand))->m_n;
3417+
uint64_t val = ~uint64_t(op_value);
3418+
value = ASR::down_cast<ASR::expr_t>(ASR::make_UnsignedIntegerConstant_t(
3419+
al, x.base.base.loc, val, operand_type));
3420+
}
3421+
tmp = ASR::make_UnsignedIntegerBitNot_t(al, x.base.base.loc, operand, dest_type, value);
3422+
return;
3423+
}
34133424
else if (ASRUtils::is_real(*operand_type)) {
34143425
throw SemanticError("Unary operator '~' not supported for floats",
34153426
x.base.base.loc);

0 commit comments

Comments
 (0)