Skip to content

Commit 3d37a9a

Browse files
committed
implemented lshift
1 parent 68774de commit 3d37a9a

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed

src/libasr/pass/intrinsic_function_registry.h

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ enum class IntrinsicScalarFunctions : int64_t {
4848
FMA,
4949
FlipSign,
5050
Mod,
51+
LShift,
5152
Trailz,
5253
FloorDiv,
5354
ListIndex,
@@ -122,6 +123,7 @@ inline std::string get_intrinsic_name(int x) {
122123
INTRINSIC_NAME_CASE(FlipSign)
123124
INTRINSIC_NAME_CASE(FloorDiv)
124125
INTRINSIC_NAME_CASE(Mod)
126+
INTRINSIC_NAME_CASE(LShift)
125127
INTRINSIC_NAME_CASE(Trailz)
126128
INTRINSIC_NAME_CASE(ListIndex)
127129
INTRINSIC_NAME_CASE(Partition)
@@ -2382,6 +2384,81 @@ namespace Mod {
23822384

23832385
} // namespace Mod
23842386

2387+
#define i_BitRshift(n, bits, t) EXPR(ASR::make_IntegerBinOp_t(al, loc, \
2388+
n, ASR::binopType::BitRShift, bits, t, nullptr))
2389+
#define i_BitLshift(n, bits, t) EXPR(ASR::make_IntegerBinOp_t(al, loc, \
2390+
n, ASR::binopType::BitLShift, bits, t, nullptr))
2391+
2392+
namespace LShift {
2393+
2394+
static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) {
2395+
ASRUtils::require_impl(x.n_args == 2,
2396+
"ASR Verify: Call to LShift must have exactly 2 arguments",
2397+
x.base.base.loc, diagnostics);
2398+
ASR::ttype_t *type1 = ASRUtils::expr_type(x.m_args[0]);
2399+
ASR::ttype_t *type2 = ASRUtils::expr_type(x.m_args[1]);
2400+
ASRUtils::require_impl((is_integer(*type1) && is_integer(*type2)),
2401+
"ASR Verify: Arguments to LShift must be of integer type",
2402+
x.base.base.loc, diagnostics);
2403+
}
2404+
2405+
static ASR::expr_t *eval_LShift(Allocator &al, const Location &loc,
2406+
ASR::ttype_t* t1, Vec<ASR::expr_t*> &args) {
2407+
int64_t a = ASR::down_cast<ASR::IntegerConstant_t>(args[0])->m_n;
2408+
int64_t b = ASR::down_cast<ASR::IntegerConstant_t>(args[1])->m_n;
2409+
int64_t val = a << b;
2410+
return make_ConstantWithType(make_IntegerConstant_t, val, t1, loc);
2411+
}
2412+
2413+
static inline ASR::asr_t* create_LShift(Allocator& al, const Location& loc,
2414+
Vec<ASR::expr_t*>& args,
2415+
const std::function<void (const std::string &, const Location &)> err) {
2416+
if (args.size() != 2) {
2417+
err("Intrinsic LShift function accepts exactly 2 arguments", loc);
2418+
}
2419+
ASR::ttype_t *type1 = ASRUtils::expr_type(args[0]);
2420+
ASR::ttype_t *type2 = ASRUtils::expr_type(args[1]);
2421+
if (!((ASRUtils::is_integer(*type1) && ASRUtils::is_integer(*type2)))) {
2422+
err("Argument of the LShift function must be Integer",
2423+
args[0]->base.loc);
2424+
}
2425+
ASR::expr_t *m_value = nullptr;
2426+
if (all_args_evaluated(args)) {
2427+
Vec<ASR::expr_t*> arg_values; arg_values.reserve(al, 2);
2428+
arg_values.push_back(al, expr_value(args[0]));
2429+
arg_values.push_back(al, expr_value(args[1]));
2430+
m_value = eval_LShift(al, loc, expr_type(args[1]), arg_values);
2431+
}
2432+
return ASR::make_IntrinsicScalarFunction_t(al, loc,
2433+
static_cast<int64_t>(IntrinsicScalarFunctions::LShift),
2434+
args.p, args.n, 0, ASRUtils::expr_type(args[0]), m_value);
2435+
}
2436+
2437+
static inline ASR::expr_t* instantiate_LShift(Allocator &al, const Location &loc,
2438+
SymbolTable *scope, Vec<ASR::ttype_t*>& arg_types, ASR::ttype_t *return_type,
2439+
Vec<ASR::call_arg_t>& new_args, int64_t /*overload_id*/) {
2440+
declare_basic_variables("_lcompilers_lshift_" + type_to_str_python(arg_types[1]));
2441+
fill_func_arg("a", arg_types[0]);
2442+
fill_func_arg("p", arg_types[1]);
2443+
auto result = declare(fn_name, return_type, ReturnVar);
2444+
/*
2445+
function LShifti32i32(a, p) result(d)
2446+
integer(int32) :: a
2447+
integer(int32) :: b
2448+
result = a << b
2449+
return result
2450+
end function
2451+
*/
2452+
body.push_back(al, b.Assignment(result, i_BitLshift(args[0], args[1], arg_types[0])));
2453+
2454+
ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args,
2455+
body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr);
2456+
scope->add_symbol(fn_name, f_sym);
2457+
return b.Call(f_sym, new_args, return_type, nullptr);
2458+
}
2459+
2460+
} // namespace LShift
2461+
23852462
namespace Trailz {
23862463

23872464
static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) {
@@ -3665,6 +3742,8 @@ namespace IntrinsicScalarFunctionRegistry {
36653742
{&FloorDiv::instantiate_FloorDiv, &FloorDiv::verify_args}},
36663743
{static_cast<int64_t>(IntrinsicScalarFunctions::Mod),
36673744
{&Mod::instantiate_Mod, &Mod::verify_args}},
3745+
{static_cast<int64_t>(IntrinsicScalarFunctions::LShift),
3746+
{&LShift::instantiate_LShift, &LShift::verify_args}},
36683747
{static_cast<int64_t>(IntrinsicScalarFunctions::Trailz),
36693748
{&Trailz::instantiate_Trailz, &Trailz::verify_args}},
36703749
{static_cast<int64_t>(IntrinsicScalarFunctions::Abs),
@@ -3793,6 +3872,8 @@ namespace IntrinsicScalarFunctionRegistry {
37933872
"floordiv"},
37943873
{static_cast<int64_t>(IntrinsicScalarFunctions::Mod),
37953874
"mod"},
3875+
{static_cast<int64_t>(IntrinsicScalarFunctions::LShift),
3876+
"lshift"},
37963877
{static_cast<int64_t>(IntrinsicScalarFunctions::Trailz),
37973878
"trailz"},
37983879
{static_cast<int64_t>(IntrinsicScalarFunctions::Expm1),
@@ -3901,6 +3982,7 @@ namespace IntrinsicScalarFunctionRegistry {
39013982
{"fma", {&FMA::create_FMA, &FMA::eval_FMA}},
39023983
{"floordiv", {&FloorDiv::create_FloorDiv, &FloorDiv::eval_FloorDiv}},
39033984
{"mod", {&Mod::create_Mod, &Mod::eval_Mod}},
3985+
{"lshift", {&LShift::create_LShift, &LShift::eval_LShift}},
39043986
{"trailz", {&Trailz::create_Trailz, &Trailz::eval_Trailz}},
39053987
{"list.index", {&ListIndex::create_ListIndex, &ListIndex::eval_list_index}},
39063988
{"list.reverse", {&ListReverse::create_ListReverse, &ListReverse::eval_list_reverse}},

0 commit comments

Comments
 (0)