-
Notifications
You must be signed in to change notification settings - Fork 176
Implement Integer compare in wasm to x86 backend #1276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c6a1c23
e36a105
e2a67dc
289f4a5
e42dd24
46e2df0
5cefa66
0f1a064
66f6b0a
8036eb9
dd7213b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,7 +16,7 @@ class X86Visitor : public WASMDecoder<X86Visitor>, | |
| public: | ||
| X86Assembler &m_a; | ||
| uint32_t cur_func_idx; | ||
| std::vector<uint32_t> unique_id; | ||
| std::vector<std::string> unique_id; | ||
|
|
||
| X86Visitor(X86Assembler &m_a, Allocator &al, | ||
| diag::Diagnostics &diagonostics, Vec<uint8_t> &code) | ||
|
|
@@ -72,22 +72,22 @@ class X86Visitor : public WASMDecoder<X86Visitor>, | |
| 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<X86Visitor>, | |
| 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); | ||
|
Comment on lines
+177
to
+182
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the last discussion, you said we can push value directly into the stack.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
How would we use the value on top of stack?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pushing the value directly into the stack works: m_a.asm_push_imm8(0);
m_a.asm_jmp_label(".compare.end_" + std::to_string(offset));
m_a.add_label(".compare_1" + std::to_string(offset));
m_a.asm_push_imm8(1);
m_a.add_label(".compare.end_" + std::to_string(offset));
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It can be accessed during run-time only.
Other instructions can use it during run-time time. They perform some operation(s) on it and store the result back onto stack.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If it works, we can use this way. (I think it could be better as it could use (slightly) lesser instructions)
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added this change/improvement into this commit |
||
| } | ||
|
|
||
| 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); | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Thirumalai-Shaktivel, please, could you possibly share why we need to store the
offsetinunique_id? Are we using it later outside thehandleI32Compare()function?If it is not used later, we need/should not store it, I think.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, I forgot to pop the uniqu_id!
Now, If I think of it, we have options:
1.
which do you prefer the most?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As you said, yup, it is not used later on. So, Instead of storing the unique_id, we can just use
std::to_string(offset). I think option 1 would be good to go.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, the reason why I used the
unique_idis that: I thought theoffsetvalue would be incremented inside thehandle_compareI32()function. I checked and it seems the offset is not modified. So, we can usestd::to_string(offset).I will make the able change with the loop stmt. Thanks for noticing it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, we can just use
offsetas a label.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I incorporated this change into this commit WASM_X86: Use offset directly as label