@@ -11,6 +11,22 @@ namespace LFortran {
11
11
12
12
namespace wasm {
13
13
14
+ /*
15
+
16
+ This X86Visitor uses stack to pass arguments and return values from functions.
17
+ Since in X86, instructions operate on registers (and not on stack),
18
+ for every instruction we pop elements from top of stack and store them into
19
+ registers. After operating on the registers, the result value is then
20
+ pushed back onto the stack.
21
+
22
+ One of the reasons to use stack to pass function arguments is that,
23
+ it allows us to define and call functions with any number of parameters.
24
+ As registers are limited in number, if we use them to pass function arugments,
25
+ the number of arguments we could pass to a function would get limited by
26
+ the number of registers available with the CPU.
27
+
28
+ */
29
+
14
30
class X86Visitor : public WASMDecoder <X86Visitor>,
15
31
public WASM_INSTS_VISITOR::BaseWASMVisitor<X86Visitor> {
16
32
public:
@@ -28,6 +44,8 @@ class X86Visitor : public WASMDecoder<X86Visitor>,
28
44
wasm_bytes.from_pointer_n (code.data (), code.size ());
29
45
}
30
46
47
+ void visit_Unreachable () {}
48
+
31
49
void visit_Return () {}
32
50
33
51
void call_imported_function (uint32_t func_index) {
@@ -70,7 +88,7 @@ class X86Visitor : public WASMDecoder<X86Visitor>,
70
88
break ;
71
89
}
72
90
case 6 : { // set_exit_code
73
- m_a.asm_call_label (" exit" );
91
+ m_a.asm_jmp_label (" exit" );
74
92
break ;
75
93
}
76
94
default : {
@@ -160,6 +178,11 @@ class X86Visitor : public WASMDecoder<X86Visitor>,
160
178
}
161
179
}
162
180
181
+ void visit_I32Eqz () {
182
+ m_a.asm_push_imm32 (0U );
183
+ handle_I32Compare (" Eq" );
184
+ }
185
+
163
186
void visit_I32Const (int32_t value) {
164
187
m_a.asm_push_imm32 (value);
165
188
// if (value < 0) {
@@ -199,31 +222,30 @@ class X86Visitor : public WASMDecoder<X86Visitor>,
199
222
}
200
223
201
224
void handle_I32Compare (const std::string &compare_op) {
202
- unique_id. push_back ( std::to_string (offset) );
225
+ std::string label = std:: to_string (offset);
203
226
m_a.asm_pop_r32 (X86Reg::ebx);
204
227
m_a.asm_pop_r32 (X86Reg::eax);
205
228
m_a.asm_cmp_r32_r32 (X86Reg::eax, X86Reg::ebx);
206
229
if (compare_op == " Eq" ) {
207
- m_a.asm_je_label (" .compare_1" + unique_id. back () );
230
+ m_a.asm_je_label (" .compare_1" + label );
208
231
} else if (compare_op == " Gt" ) {
209
- m_a.asm_jg_label (" .compare_1" + unique_id. back () );
232
+ m_a.asm_jg_label (" .compare_1" + label );
210
233
} else if (compare_op == " GtE" ) {
211
- m_a.asm_jge_label (" .compare_1" + unique_id. back () );
234
+ m_a.asm_jge_label (" .compare_1" + label );
212
235
} else if (compare_op == " Lt" ) {
213
- m_a.asm_jl_label (" .compare_1" + unique_id. back () );
236
+ m_a.asm_jl_label (" .compare_1" + label );
214
237
} else if (compare_op == " LtE" ) {
215
- m_a.asm_jle_label (" .compare_1" + unique_id. back () );
238
+ m_a.asm_jle_label (" .compare_1" + label );
216
239
} else if (compare_op == " NotEq" ) {
217
- m_a.asm_jne_label (" .compare_1" + unique_id. back () );
240
+ m_a.asm_jne_label (" .compare_1" + label );
218
241
} else {
219
242
throw CodeGenError (" Comparison operator not implemented" );
220
243
}
221
- m_a.asm_mov_r32_imm32 (X86Reg::eax, 0 );
222
- m_a.asm_jmp_label (" .compare.end_" + unique_id.back ());
223
- m_a.add_label (" .compare_1" + unique_id.back ());
224
- m_a.asm_mov_r32_imm32 (X86Reg::eax, 1 );
225
- m_a.add_label (" .compare.end_" + unique_id.back ());
226
- m_a.asm_push_r32 (X86Reg::eax);
244
+ m_a.asm_push_imm8 (0 );
245
+ m_a.asm_jmp_label (" .compare.end_" + label);
246
+ m_a.add_label (" .compare_1" + label);
247
+ m_a.asm_push_imm8 (1 );
248
+ m_a.add_label (" .compare.end_" + label);
227
249
}
228
250
229
251
void visit_I32Eq () { handle_I32Compare (" Eq" ); }
@@ -238,7 +260,7 @@ class X86Visitor : public WASMDecoder<X86Visitor>,
238
260
239
261
// Add runtime library functions
240
262
emit_print_int (m_a, " print_i32" );
241
- emit_exit (m_a, " exit" , 0 );
263
+ emit_exit2 (m_a, " exit" );
242
264
243
265
// declare compile-time strings
244
266
for (uint32_t i = 0 ; i < data_segments.size (); i++) {
0 commit comments