Skip to content

Commit f902d38

Browse files
ubaidskcertik
authored andcommitted
ASR,LLVM,C: Support unsigned int unary minus
1 parent 9d5b472 commit f902d38

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
lines changed

src/libasr/codegen/asr_to_c_cpp.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2062,6 +2062,12 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) {
20622062
handle_UnaryMinus(x);
20632063
}
20642064

2065+
void visit_UnsignedIntegerUnaryMinus(const ASR::UnsignedIntegerUnaryMinus_t &x) {
2066+
handle_UnaryMinus(x);
2067+
int kind = ASRUtils::extract_kind_from_ttype_t(ASRUtils::expr_type(x.m_arg));
2068+
src = "(uint" + std::to_string(kind * 8) + "_t)" + src;
2069+
}
2070+
20652071
void visit_RealUnaryMinus(const ASR::RealUnaryMinus_t &x) {
20662072
handle_UnaryMinus(x);
20672073
}

src/libasr/codegen/asr_to_llvm.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6208,6 +6208,17 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
62086208
tmp = builder->CreateSub(zero, tmp);
62096209
}
62106210

6211+
void visit_UnsignedIntegerUnaryMinus(const ASR::UnsignedIntegerUnaryMinus_t &x) {
6212+
if (x.m_value) {
6213+
this->visit_expr_wrapper(x.m_value, true);
6214+
return;
6215+
}
6216+
this->visit_expr_wrapper(x.m_arg, true);
6217+
int kind = ASRUtils::extract_kind_from_ttype_t(ASRUtils::expr_type(x.m_arg));
6218+
llvm::Value *one = llvm::ConstantInt::get(context, llvm::APInt(kind * 8, 1, true));
6219+
tmp = builder->CreateAdd(builder->CreateNot(tmp), one); // compute 2's complement
6220+
}
6221+
62116222
void visit_RealUnaryMinus(const ASR::RealUnaryMinus_t &x) {
62126223
if (x.m_value) {
62136224
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
@@ -3572,6 +3572,17 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
35723572
tmp = ASR::make_IntegerUnaryMinus_t(al, x.base.base.loc, operand,
35733573
operand_type, value);
35743574
return;
3575+
} else if (ASRUtils::is_unsigned_integer(*operand_type)) {
3576+
if (ASRUtils::expr_value(operand) != nullptr) {
3577+
int64_t op_value = ASR::down_cast<ASR::UnsignedIntegerConstant_t>(
3578+
ASRUtils::expr_value(operand))->m_n;
3579+
op_value = (~op_value) + 1; // compute 2's complement
3580+
value = ASR::down_cast<ASR::expr_t>(ASR::make_UnsignedIntegerConstant_t(
3581+
al, x.base.base.loc, op_value, operand_type));
3582+
}
3583+
tmp = ASR::make_UnsignedIntegerUnaryMinus_t(al, x.base.base.loc, operand,
3584+
operand_type, value);
3585+
return;
35753586
} else if (ASRUtils::is_real(*operand_type)) {
35763587
if (ASRUtils::expr_value(operand) != nullptr) {
35773588
double op_value = ASR::down_cast<ASR::RealConstant_t>(

0 commit comments

Comments
 (0)