diff --git a/source/compiler/test/main.s b/source/compiler/test/main.s index ab221280..f0227411 100644 --- a/source/compiler/test/main.s +++ b/source/compiler/test/main.s @@ -5,11 +5,9 @@ // - numerical literals throw cast warnings, which shouldnt happen // TODO: -// - check for memory oversteps in the parser // - add namespaces to error messages, whenever applicable (ie. x::y::test) -// - namespace directives should probably be a part of the function signature? - // - cleanup ir gen alignment sizes (u64 vs u32 vs u16) +// - conjunction & disjunction operators // CHECK: // - bool b = 100 > 200; diff --git a/source/intermediate_representation/builder.cpp b/source/intermediate_representation/builder.cpp index 1c08c2df..69f560fc 100644 --- a/source/intermediate_representation/builder.cpp +++ b/source/intermediate_representation/builder.cpp @@ -138,6 +138,21 @@ namespace sigma::ir { return get_insert_point_checked()->create_cmp_ige(a, b, is_signed); } + auto builder::create_not(handle value) const -> handle { + DEBUG_PRINT("creating not"); + return get_insert_point_checked()->create_not(value); + } + + auto builder::create_and(handle a, handle b) const -> handle { + DEBUG_PRINT("creating and"); + return get_insert_point_checked()->create_and(a, b); + } + + auto builder::create_or(handle a, handle b) const -> handle { + DEBUG_PRINT("creating or"); + return get_insert_point_checked()->create_or(a, b); + } + auto builder::create_sxt(handle src, data_type dt) const -> handle { DEBUG_PRINT("creating sxt"); return get_insert_point_checked()->create_sxt(src, dt); diff --git a/source/intermediate_representation/builder.h b/source/intermediate_representation/builder.h index a957f992..e48e98fa 100644 --- a/source/intermediate_representation/builder.h +++ b/source/intermediate_representation/builder.h @@ -148,6 +148,11 @@ namespace sigma::ir { auto create_cmp_igt(handle a, handle b, bool is_signed) const -> handle; auto create_cmp_ige(handle a, handle b, bool is_signed) const -> handle; + // bitwise operations + auto create_not(handle value) const -> handle; + auto create_and(handle a, handle b) const -> handle; + auto create_or(handle a, handle b) const -> handle; + // casting auto create_sxt(handle src, data_type dt) const -> handle; auto create_zxt(handle src, data_type dt) const -> handle; diff --git a/source/intermediate_representation/node_hierarchy/function.cpp b/source/intermediate_representation/node_hierarchy/function.cpp index db936f8d..823910f4 100644 --- a/source/intermediate_representation/node_hierarchy/function.cpp +++ b/source/intermediate_representation/node_hierarchy/function.cpp @@ -190,27 +190,42 @@ namespace sigma::ir { } auto function::create_cmp_eq(handle a, handle b) -> handle { - return create_cmp(node::type::CMP_EQ, a, b); + return create_cmp_operation(node::type::CMP_EQ, a, b); } auto function::create_cmp_ne(handle a, handle b) -> handle { - return create_cmp(node::type::CMP_NE, a, b); + return create_cmp_operation(node::type::CMP_NE, a, b); } auto function::create_cmp_ilt(handle a, handle b, bool is_signed) -> handle { - return create_cmp(is_signed ? node::type::CMP_SLT : node::type::CMP_ULT, a, b); + return create_cmp_operation(is_signed ? node::type::CMP_SLT : node::type::CMP_ULT, a, b); } auto function::create_cmp_ile(handle a, handle b, bool is_signed) -> handle { - return create_cmp(is_signed ? node::type::CMP_SLE : node::type::CMP_ULE, a, b); + return create_cmp_operation(is_signed ? node::type::CMP_SLE : node::type::CMP_ULE, a, b); } auto function::create_cmp_igt(handle a, handle b, bool is_signed) -> handle { - return create_cmp(is_signed ? node::type::CMP_SLT : node::type::CMP_ULT, a, b); + return create_cmp_operation(is_signed ? node::type::CMP_SLT : node::type::CMP_ULT, a, b); } auto function::create_cmp_ige(handle a, handle b, bool is_signed) -> handle { - return create_cmp(is_signed ? node::type::CMP_SLE : node::type::CMP_ULE, a, b); + return create_cmp_operation(is_signed ? node::type::CMP_SLE : node::type::CMP_ULE, a, b); + } + + auto function::create_not(handle value) -> handle { + const handle n = create_node(node::type::NOT, 2); + n->inputs[1] = value; + return n; + } + + auto function::create_and(handle a, handle b) -> handle { + // bitwise operators can't wrap + return create_binary_arithmetic_operation(node::type::AND, a, b, arithmetic_behaviour::NONE); + } + + auto function::create_or(handle a, handle b) -> handle { + return create_binary_arithmetic_operation(node::type::OR, a, b, arithmetic_behaviour::NONE); } void function::create_store(handle destination, handle value, u32 alignment, bool is_volatile) { @@ -306,14 +321,14 @@ namespace sigma::ir { auto function::create_binary_arithmetic_operation(node::type type, handle left, handle right, arithmetic_behaviour behaviour) -> handle { ASSERT(left->dt == right->dt, "data types of the two operands do not match"); - const handle operation = create_node(type, 3); + const handle op = create_node(type, 3); - operation->get().behaviour = behaviour; - operation->inputs[1] = left; - operation->inputs[2] = right; - operation->dt = left->dt; + op->get().behaviour = behaviour; + op->inputs[1] = left; + op->inputs[2] = right; + op->dt = left->dt; - return operation; + return op; } auto function::create_unary_operation(node::type type, data_type dt, handle src) -> handle { @@ -323,7 +338,7 @@ namespace sigma::ir { return operation; } - auto function::create_cmp(node::type type, handle a, handle b) -> handle { + auto function::create_cmp_operation(node::type type, handle a, handle b) -> handle { ASSERT(a->dt == b->dt, "data types of the two operands do not match"); const handle cmp = create_node(type, 3); diff --git a/source/intermediate_representation/node_hierarchy/function.h b/source/intermediate_representation/node_hierarchy/function.h index 9785aad7..286530d2 100644 --- a/source/intermediate_representation/node_hierarchy/function.h +++ b/source/intermediate_representation/node_hierarchy/function.h @@ -72,6 +72,11 @@ namespace sigma::ir { auto create_cmp_igt(handle a, handle b, bool is_signed) -> handle; auto create_cmp_ige(handle a, handle b, bool is_signed) -> handle; + // bitwise operations + auto create_not(handle value) -> handle; + auto create_and(handle a, handle b) -> handle; + auto create_or(handle a, handle b) -> handle; + void create_store(handle destination, handle value, u32 alignment, bool is_volatile); auto create_load(handle value_to_load, data_type data_type, u32 alignment, bool is_volatile) -> handle; auto create_array_access(handle base, handle index, i64 stride) -> handle ; @@ -82,8 +87,9 @@ namespace sigma::ir { auto create_call(const function_signature& function_sig, handle callee_symbol_address,const std::vector>& arguments) -> handle; auto create_binary_arithmetic_operation(node::type type, handle left, handle right, arithmetic_behaviour behaviour) -> handle; + auto create_unary_operation(node::type type, data_type dt, handle src) -> handle; - auto create_cmp(node::type type, handle a, handle b) -> handle; + auto create_cmp_operation(node::type type, handle a, handle b) -> handle; auto create_projection(data_type dt, handle source, u64 index) -> handle; auto append_memory(handle memory) const -> handle;