diff --git a/integration_tests/if_02.py b/integration_tests/if_02.py new file mode 100644 index 0000000000..e2dd52f6ff --- /dev/null +++ b/integration_tests/if_02.py @@ -0,0 +1,42 @@ +from ltypes import bool, i32 + +def test_if_01(): + x: bool = True + y: i32 = 10 + z: i32 = 0 + + if x: + x = False + if x: + z += 1 + else: + z += 1 + + if y > 5: + z += 1 + if y < 12: + z += 1 + if y == 10: + z += 1 + if y != 10: + z += 1 + else: + z += 1 + if y <= 10: + z += 1 + + y = 5 + if y <= 10: + z += 1 + if y >= 5: + z += 1 + if y >= 2: + z += 1 + + # TODO: replace this an assert statement + print(z) + +def verify(): + test_if_01() + +verify() diff --git a/src/libasr/codegen/wasm_to_x86.cpp b/src/libasr/codegen/wasm_to_x86.cpp index c298349a20..755caffced 100644 --- a/src/libasr/codegen/wasm_to_x86.cpp +++ b/src/libasr/codegen/wasm_to_x86.cpp @@ -16,7 +16,7 @@ class X86Visitor : public WASMDecoder, public: X86Assembler &m_a; uint32_t cur_func_idx; - std::vector unique_id; + std::vector unique_id; X86Visitor(X86Assembler &m_a, Allocator &al, diag::Diagnostics &diagonostics, Vec &code) @@ -72,22 +72,22 @@ class X86Visitor : public WASMDecoder, void visit_EmtpyBlockType() {} void visit_If() { - unique_id.push_back(offset); + unique_id.push_back(std::to_string(offset)); m_a.asm_pop_r32(X86Reg::eax); m_a.asm_cmp_r32_imm8(LFortran::X86Reg::eax, 1); - m_a.asm_je_label(".then_" + std::to_string(unique_id.back())); - m_a.asm_jmp_label(".else_" + std::to_string(unique_id.back())); - m_a.add_label(".then_" + std::to_string(unique_id.back())); + m_a.asm_je_label(".then_" + unique_id.back()); + m_a.asm_jmp_label(".else_" + unique_id.back()); + m_a.add_label(".then_" + unique_id.back()); { decode_instructions(); } - m_a.add_label(".endif_" + std::to_string(unique_id.back())); + m_a.add_label(".endif_" + unique_id.back()); unique_id.pop_back(); } void visit_Else() { - m_a.asm_jmp_label(".endif_" + std::to_string(unique_id.back())); - m_a.add_label(".else_" + std::to_string(unique_id.back())); + m_a.asm_jmp_label(".endif_" + unique_id.back()); + m_a.add_label(".else_" + unique_id.back()); } void visit_LocalGet(uint32_t localidx) { @@ -154,6 +154,41 @@ class X86Visitor : public WASMDecoder, m_a.asm_push_r32(X86Reg::eax); } + void handle_I32Compare(const std::string &compare_op) { + unique_id.push_back(std::to_string(offset)); + m_a.asm_pop_r32(X86Reg::ebx); + m_a.asm_pop_r32(X86Reg::eax); + m_a.asm_cmp_r32_r32(X86Reg::eax, X86Reg::ebx); + if (compare_op == "Eq") { + m_a.asm_je_label(".compare_1" + unique_id.back()); + } else if (compare_op == "Gt") { + m_a.asm_jg_label(".compare_1" + unique_id.back()); + } else if (compare_op == "GtE") { + m_a.asm_jge_label(".compare_1" + unique_id.back()); + } else if (compare_op == "Lt") { + m_a.asm_jl_label(".compare_1" + unique_id.back()); + } else if (compare_op == "LtE") { + m_a.asm_jle_label(".compare_1" + unique_id.back()); + } else if (compare_op == "NotEq") { + m_a.asm_jne_label(".compare_1" + unique_id.back()); + } else { + throw CodeGenError("Comparison operator not implemented"); + } + m_a.asm_mov_r32_imm32(X86Reg::eax, 0); + m_a.asm_jmp_label(".compare.end_" + unique_id.back()); + m_a.add_label(".compare_1" + unique_id.back()); + m_a.asm_mov_r32_imm32(X86Reg::eax, 1); + m_a.add_label(".compare.end_" + unique_id.back()); + m_a.asm_push_r32(X86Reg::eax); + } + + void visit_I32Eq() { handle_I32Compare("Eq"); } + void visit_I32GtS() { handle_I32Compare("Gt"); } + void visit_I32GeS() { handle_I32Compare("GtE"); } + void visit_I32LtS() { handle_I32Compare("Lt"); } + void visit_I32LeS() { handle_I32Compare("LtE"); } + void visit_I32Ne() { handle_I32Compare("NotEq"); } + void gen_x86_bytes() { emit_elf32_header(m_a);