Skip to content

Commit b55d10b

Browse files
authored
Merge pull request #1265 from Shaikh-Ubaid/wasm_x86_print_str
WASM_X86: Initial support for print_str
2 parents dcbb524 + c5c9f57 commit b55d10b

File tree

1 file changed

+67
-11
lines changed

1 file changed

+67
-11
lines changed

src/libasr/codegen/wasm_to_x86.cpp

Lines changed: 67 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ class X86Visitor : public WASMDecoder<X86Visitor>,
1717
X86Assembler &m_a;
1818
uint32_t cur_func_idx;
1919
std::vector<std::string> unique_id;
20+
int32_t last_vis_i32_const, last_last_vis_i32_const;
21+
std::unordered_map<int32_t, std::string> loc_to_str;
2022

2123
X86Visitor(X86Assembler &m_a, Allocator &al,
2224
diag::Diagnostics &diagonostics, Vec<uint8_t> &code)
@@ -28,20 +30,58 @@ class X86Visitor : public WASMDecoder<X86Visitor>,
2830

2931
void visit_Return() {}
3032

31-
void visit_Call(uint32_t func_index) {
32-
if (func_index <= 6U) {
33-
// call to imported functions
34-
if (func_index == 0) {
33+
void call_imported_function(uint32_t func_index) {
34+
switch (func_index) {
35+
case 0: { // print_i32
3536
m_a.asm_call_label("print_i32");
36-
} else if (func_index == 5) {
37-
// currently ignoring flush_buf
38-
} else if (func_index == 6) {
37+
break;
38+
}
39+
case 1: { // print_i64
40+
std::cerr << "Call to print_i64() is not yet supported";
41+
break;
42+
}
43+
case 2: { // print_f32
44+
std::cerr << "Call to print_f32() is not yet supported";
45+
break;
46+
}
47+
case 3: { // print_f64
48+
std::cerr << "Call to print_f64() is not yet supported";
49+
break;
50+
}
51+
case 4: { // print_str
52+
{
53+
// pop the string length and string location
54+
// we do not need them at the moment
55+
m_a.asm_pop_r32(X86Reg::eax);
56+
m_a.asm_pop_r32(X86Reg::eax);
57+
}
58+
std::string label =
59+
"string" + std::to_string(last_last_vis_i32_const);
60+
emit_print(m_a, label,
61+
loc_to_str[last_last_vis_i32_const].size());
62+
break;
63+
}
64+
case 5: { // flush_buf
65+
std::string label = "string-1";
66+
std::string msg = "\n";
67+
int32_t loc = -1; // tmp negative index used
68+
emit_print(m_a, label, msg.size());
69+
loc_to_str[loc] = msg;
70+
break;
71+
}
72+
case 6: { // set_exit_code
3973
m_a.asm_call_label("exit");
40-
} else {
41-
std::cerr << "Call to imported function with index " +
42-
std::to_string(func_index) +
43-
" not yet supported";
74+
break;
75+
}
76+
default: {
77+
std::cerr << "Unsupported func_index";
4478
}
79+
}
80+
}
81+
82+
void visit_Call(uint32_t func_index) {
83+
if (func_index <= 6U) {
84+
call_imported_function(func_index);
4585
return;
4686
}
4787

@@ -127,6 +167,10 @@ class X86Visitor : public WASMDecoder<X86Visitor>,
127167
// m_a.asm_neg_r32(X86Reg::eax);
128168
// m_a.asm_push_r32(X86Reg::eax);
129169
// }
170+
171+
// TODO: Following seems/is hackish. Fix/Improve it.
172+
last_last_vis_i32_const = last_vis_i32_const;
173+
last_vis_i32_const = value;
130174
}
131175

132176
void visit_I32Add() {
@@ -196,6 +240,13 @@ class X86Visitor : public WASMDecoder<X86Visitor>,
196240
emit_print_int(m_a, "print_i32");
197241
emit_exit(m_a, "exit", 0);
198242

243+
// declare compile-time strings
244+
for (uint32_t i = 0; i < data_segments.size(); i++) {
245+
offset = data_segments[i].insts_start_index;
246+
decode_instructions();
247+
loc_to_str[last_vis_i32_const] = data_segments[i].text;
248+
}
249+
199250
for (uint32_t i = 0; i < type_indices.size(); i++) {
200251
if (i < type_indices.size() - 1U) {
201252
m_a.add_label(exports[i].name);
@@ -228,6 +279,11 @@ class X86Visitor : public WASMDecoder<X86Visitor>,
228279
}
229280
}
230281

282+
for (auto &s : loc_to_str) {
283+
std::string label = "string" + std::to_string(s.first);
284+
emit_data_string(m_a, label, s.second);
285+
}
286+
231287
emit_elf32_footer(m_a);
232288
}
233289
};

0 commit comments

Comments
 (0)