@@ -32,7 +32,8 @@ class X86Visitor : public WASMDecoder<X86Visitor>,
3232 public:
3333 X86Assembler &m_a;
3434 uint32_t cur_func_idx;
35- std::vector<std::string> unique_id;
35+ std::vector<std::string> if_unique_id;
36+ std::vector<std::string> loop_unique_id;
3637 int32_t last_vis_i32_const, last_last_vis_i32_const;
3738 std::unordered_map<int32_t , std::string> loc_to_str;
3839
@@ -129,23 +130,59 @@ class X86Visitor : public WASMDecoder<X86Visitor>,
129130
130131 void visit_EmtpyBlockType () {}
131132
133+ void visit_Br (uint32_t label_index) {
134+ // Branch is used to jump to the `loop.head` or `loop.end`.
135+ if (if_unique_id.size () - loop_unique_id.size () == label_index - 1 ) {
136+ // cycle/continue or loop.end
137+ m_a.asm_jmp_label (" .loop.head_" + loop_unique_id.back ());
138+ } else {
139+ // exit/break
140+ m_a.asm_jmp_label (" .loop.end_" + loop_unique_id.back ());
141+ }
142+ }
143+
144+ void visit_Loop () {
145+ loop_unique_id.push_back (std::to_string (offset));
146+ /*
147+ The loop statement starts with `loop.head`. The `loop.body` and
148+ `loop.branch` are enclosed within the `if.block`. If the condition
149+ fails, the loop is exited through `else.block`.
150+ .head
151+ .If
152+ # Statements
153+ .Br
154+ .Else
155+ .endIf
156+ .end
157+ */
158+ m_a.add_label (" .loop.head_" + loop_unique_id.back ());
159+ {
160+ decode_instructions ();
161+ }
162+ // end
163+ m_a.add_label (" .loop.end_" + loop_unique_id.back ());
164+ loop_unique_id.pop_back ();
165+ }
166+
132167 void visit_If () {
133- unique_id.push_back (std::to_string (offset));
168+ if_unique_id.push_back (std::to_string (offset));
169+ // `eax` contains the logical value (true = 1, false = 0)
170+ // of the if condition
134171 m_a.asm_pop_r32 (X86Reg::eax);
135172 m_a.asm_cmp_r32_imm8 (LFortran::X86Reg::eax, 1 );
136- m_a.asm_je_label (" .then_" + unique_id .back ());
137- m_a.asm_jmp_label (" .else_" + unique_id .back ());
138- m_a.add_label (" .then_" + unique_id .back ());
173+ m_a.asm_je_label (" .then_" + if_unique_id .back ());
174+ m_a.asm_jmp_label (" .else_" + if_unique_id .back ());
175+ m_a.add_label (" .then_" + if_unique_id .back ());
139176 {
140177 decode_instructions ();
141178 }
142- m_a.add_label (" .endif_" + unique_id .back ());
143- unique_id .pop_back ();
179+ m_a.add_label (" .endif_" + if_unique_id .back ());
180+ if_unique_id .pop_back ();
144181 }
145182
146183 void visit_Else () {
147- m_a.asm_jmp_label (" .endif_" + unique_id .back ());
148- m_a.add_label (" .else_" + unique_id .back ());
184+ m_a.asm_jmp_label (" .endif_" + if_unique_id .back ());
185+ m_a.add_label (" .else_" + if_unique_id .back ());
149186 }
150187
151188 void visit_LocalGet (uint32_t localidx) {
@@ -225,6 +262,7 @@ class X86Visitor : public WASMDecoder<X86Visitor>,
225262 std::string label = std::to_string (offset);
226263 m_a.asm_pop_r32 (X86Reg::ebx);
227264 m_a.asm_pop_r32 (X86Reg::eax);
265+ // `eax` and `ebx` contain the left and right operands, respectively
228266 m_a.asm_cmp_r32_r32 (X86Reg::eax, X86Reg::ebx);
229267 if (compare_op == " Eq" ) {
230268 m_a.asm_je_label (" .compare_1" + label);
@@ -241,6 +279,8 @@ class X86Visitor : public WASMDecoder<X86Visitor>,
241279 } else {
242280 throw CodeGenError (" Comparison operator not implemented" );
243281 }
282+ // if the `compare` condition in `true`, jump to compare_1
283+ // and assign `1` else assign `0`
244284 m_a.asm_push_imm8 (0 );
245285 m_a.asm_jmp_label (" .compare.end_" + label);
246286 m_a.add_label (" .compare_1" + label);
0 commit comments