@@ -2867,6 +2867,36 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
28672867 }
28682868 break ;
28692869 }
2870+ case (ASR::ttypeType::UnsignedInteger) : {
2871+ ASR::UnsignedInteger_t* v_type = down_cast<ASR::UnsignedInteger_t>(asr_type);
2872+ m_dims = v_type->m_dims ;
2873+ n_dims = v_type->n_dims ;
2874+ a_kind = v_type->m_kind ;
2875+ if ( n_dims > 0 ) {
2876+ if ( m_abi == ASR::abiType::BindC ) {
2877+ if ( ASRUtils::is_fixed_size_array (v_type->m_dims , v_type->n_dims ) ) {
2878+ llvm_type = llvm::ArrayType::get (get_el_type (asr_type), ASRUtils::get_fixed_size_of_array (
2879+ v_type->m_dims , v_type->n_dims ));
2880+ } else {
2881+ llvm_type = get_el_type (asr_type)->getPointerTo ();
2882+ }
2883+ } else {
2884+ is_array_type = true ;
2885+ llvm::Type* el_type = get_el_type (asr_type);
2886+ if ( m_storage == ASR::storage_typeType::Allocatable ) {
2887+ is_malloc_array_type = true ;
2888+ llvm_type = arr_descr->get_malloc_array_type (asr_type, el_type);
2889+ } else {
2890+ llvm_type = arr_descr->get_array_type (asr_type, el_type);
2891+ }
2892+ }
2893+ } else {
2894+ // LLVM does not distinguish signed and unsigned integer types
2895+ // Only integer operations can be signed/unsigned
2896+ llvm_type = getIntType (a_kind);
2897+ }
2898+ break ;
2899+ }
28702900 case (ASR::ttypeType::Real) : {
28712901 ASR::Real_t* v_type = down_cast<ASR::Real_t>(asr_type);
28722902 m_dims = v_type->m_dims ;
@@ -3459,6 +3489,34 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
34593489 }
34603490 break ;
34613491 }
3492+ case (ASR::ttypeType::UnsignedInteger) : {
3493+ ASR::UnsignedInteger_t* v_type = down_cast<ASR::UnsignedInteger_t>(asr_type);
3494+ n_dims = v_type->n_dims ;
3495+ a_kind = v_type->m_kind ;
3496+ if ( n_dims > 0 ) {
3497+ if (m_abi == ASR::abiType::BindC ||
3498+ (!ASRUtils::is_dimension_empty (v_type->m_dims , v_type->n_dims ))) {
3499+ // Bind(C) arrays are represened as a pointer
3500+ type = getIntType (a_kind, true );
3501+ } else {
3502+ is_array_type = true ;
3503+ llvm::Type* el_type = get_el_type (asr_type);
3504+ if ( m_storage == ASR::storage_typeType::Allocatable ) {
3505+ type = arr_descr->get_malloc_array_type (asr_type, el_type, get_pointer);
3506+ } else {
3507+ type = arr_descr->get_array_type (asr_type, el_type, get_pointer);
3508+ }
3509+ }
3510+ } else {
3511+ if (arg_m_abi == ASR::abiType::BindC
3512+ && arg_m_value_attr) {
3513+ type = getIntType (a_kind, false );
3514+ } else {
3515+ type = getIntType (a_kind, true );
3516+ }
3517+ }
3518+ break ;
3519+ }
34623520 case (ASR::ttypeType::Pointer) : {
34633521 ASR::ttype_t *t2 = ASRUtils::type_get_past_pointer (asr_type);
34643522 bool is_pointer_ = ASR::is_a<ASR::Class_t>(*t2);
@@ -3904,6 +3962,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
39043962 return_type = getIntType (a_kind);
39053963 break ;
39063964 }
3965+ case (ASR::ttypeType::UnsignedInteger) : {
3966+ int a_kind = down_cast<ASR::UnsignedInteger_t>(return_var_type0)->m_kind ;
3967+ return_type = getIntType (a_kind);
3968+ break ;
3969+ }
39073970 case (ASR::ttypeType::Real) : {
39083971 int a_kind = down_cast<ASR::Real_t>(return_var_type0)->m_kind ;
39093972 return_type = getFPType (a_kind);
@@ -5019,6 +5082,47 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
50195082 }
50205083 }
50215084
5085+ void visit_UnsignedIntegerCompare (const ASR::UnsignedIntegerCompare_t &x) {
5086+ if (x.m_value ) {
5087+ this ->visit_expr_wrapper (x.m_value , true );
5088+ return ;
5089+ }
5090+ this ->visit_expr_wrapper (x.m_left , true );
5091+ llvm::Value *left = tmp;
5092+ this ->visit_expr_wrapper (x.m_right , true );
5093+ llvm::Value *right = tmp;
5094+ switch (x.m_op ) {
5095+ case (ASR::cmpopType::Eq) : {
5096+ tmp = builder->CreateICmpEQ (left, right);
5097+ break ;
5098+ }
5099+ case (ASR::cmpopType::Gt) : {
5100+ tmp = builder->CreateICmpUGT (left, right);
5101+ break ;
5102+ }
5103+ case (ASR::cmpopType::GtE) : {
5104+ tmp = builder->CreateICmpUGE (left, right);
5105+ break ;
5106+ }
5107+ case (ASR::cmpopType::Lt) : {
5108+ tmp = builder->CreateICmpULT (left, right);
5109+ break ;
5110+ }
5111+ case (ASR::cmpopType::LtE) : {
5112+ tmp = builder->CreateICmpULE (left, right);
5113+ break ;
5114+ }
5115+ case (ASR::cmpopType::NotEq) : {
5116+ tmp = builder->CreateICmpNE (left, right);
5117+ break ;
5118+ }
5119+ default : {
5120+ throw CodeGenError (" Comparison operator not implemented" ,
5121+ x.base .base .loc );
5122+ }
5123+ }
5124+ }
5125+
50225126 void visit_RealCompare (const ASR::RealCompare_t &x) {
50235127 if (x.m_value ) {
50245128 this ->visit_expr_wrapper (x.m_value , true );
@@ -5498,7 +5602,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
54985602 tmp = lfortran_str_slice (str, left, right, step, left_present, right_present);
54995603 }
55005604
5501- void visit_IntegerBinOp (const ASR::IntegerBinOp_t &x) {
5605+ template <typename T>
5606+ void handle_SU_IntegerBinOp (const T &x) {
55025607 if (x.m_value ) {
55035608 this ->visit_expr_wrapper (x.m_value , true );
55045609 return ;
@@ -5507,7 +5612,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
55075612 llvm::Value *left_val = tmp;
55085613 this ->visit_expr_wrapper (x.m_right , true );
55095614 llvm::Value *right_val = tmp;
5510- LCOMPILERS_ASSERT (ASRUtils::is_integer (*x.m_type ))
5615+ LCOMPILERS_ASSERT (ASRUtils::is_integer (*x.m_type ) ||
5616+ ASRUtils::is_unsigned_integer (*x.m_type ))
55115617 switch (x.m_op ) {
55125618 case ASR::binopType::Add: {
55135619 tmp = builder->CreateAdd (left_val, right_val);
@@ -5571,6 +5677,14 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
55715677 }
55725678 }
55735679
5680+ void visit_IntegerBinOp (const ASR::IntegerBinOp_t &x) {
5681+ handle_SU_IntegerBinOp (x);
5682+ }
5683+
5684+ void visit_UnsignedIntegerBinOp (const ASR::UnsignedIntegerBinOp_t &x) {
5685+ handle_SU_IntegerBinOp (x);
5686+ }
5687+
55745688 void visit_RealBinOp (const ASR::RealBinOp_t &x) {
55755689 if (x.m_value ) {
55765690 this ->visit_expr_wrapper (x.m_value , true );
@@ -5776,11 +5890,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
57765890 tmp = lfortran_complex_bin_op (zero_c, c, f_name, type);
57775891 }
57785892
5779- void visit_IntegerConstant (const ASR::IntegerConstant_t &x) {
5893+ template <typename T>
5894+ void handle_SU_IntegerConstant (const T &x) {
57805895 int64_t val = x.m_n ;
57815896 int a_kind = ASRUtils::extract_kind_from_ttype_t (x.m_type );
57825897 switch ( a_kind ) {
5783-
57845898 case 1 : {
57855899 tmp = llvm::ConstantInt::get (context, llvm::APInt (8 , val, true ));
57865900 break ;
@@ -5805,6 +5919,14 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
58055919 }
58065920 }
58075921
5922+ void visit_IntegerConstant (const ASR::IntegerConstant_t &x) {
5923+ handle_SU_IntegerConstant (x);
5924+ }
5925+
5926+ void visit_UnsignedIntegerConstant (const ASR::UnsignedIntegerConstant_t &x) {
5927+ handle_SU_IntegerConstant (x);
5928+ }
5929+
58085930 void visit_RealConstant (const ASR::RealConstant_t &x) {
58095931 double val = x.m_r ;
58105932 int a_kind = ((ASR::Real_t*)(&(x.m_type ->base )))->m_kind ;
@@ -6385,6 +6507,24 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
63856507 }
63866508 break ;
63876509 }
6510+ case (ASR::cast_kindType::IntegerToUnsignedInteger) : {
6511+ int arg_kind = -1 , dest_kind = -1 ;
6512+ extract_kinds (x, arg_kind, dest_kind);
6513+ if ( arg_kind > 0 && dest_kind > 0 &&
6514+ arg_kind != dest_kind )
6515+ {
6516+ if (dest_kind > arg_kind) {
6517+ tmp = builder->CreateSExt (tmp, getIntType (dest_kind));
6518+ } else {
6519+ tmp = builder->CreateTrunc (tmp, getIntType (dest_kind));
6520+ }
6521+ }
6522+ break ;
6523+ }
6524+ case (ASR::cast_kindType::UnsignedIntegerToInteger) : {
6525+ // tmp = tmp
6526+ break ;
6527+ }
63886528 case (ASR::cast_kindType::ComplexToComplex) : {
63896529 llvm::Type *target_type;
63906530 int arg_kind = -1 , dest_kind = -1 ;
@@ -6698,6 +6838,31 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
66986838 }
66996839 }
67006840 args.push_back (tmp);
6841+ } else if (ASRUtils::is_unsigned_integer (*t)) {
6842+ switch ( a_kind ) {
6843+ case 1 : {
6844+ fmt.push_back (" %hhi" );
6845+ break ;
6846+ }
6847+ case 2 : {
6848+ fmt.push_back (" %hi" );
6849+ break ;
6850+ }
6851+ case 4 : {
6852+ fmt.push_back (" %d" );
6853+ break ;
6854+ }
6855+ case 8 : {
6856+ fmt.push_back (" %lld" );
6857+ break ;
6858+ }
6859+ default : {
6860+ throw CodeGenError (R"""( Printing support is available only
6861+ for 8, 16, 32, and 64 bit unsigned integer kinds.)""" ,
6862+ x.base .base .loc );
6863+ }
6864+ }
6865+ args.push_back (tmp);
67016866 } else if (ASRUtils::is_real (*t)) {
67026867 llvm::Value *d;
67036868 switch ( a_kind ) {
@@ -7093,6 +7258,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
70937258 target_type = getIntType (a_kind);
70947259 break ;
70957260 }
7261+ case (ASR::ttypeType::UnsignedInteger) : {
7262+ int a_kind = down_cast<ASR::UnsignedInteger_t>(arg_type)->m_kind ;
7263+ target_type = getIntType (a_kind);
7264+ break ;
7265+ }
70967266 case (ASR::ttypeType::Real) : {
70977267 int a_kind = down_cast<ASR::Real_t>(arg_type)->m_kind ;
70987268 target_type = getFPType (a_kind);
0 commit comments