Skip to content
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

WASM_X64: Support printing integers #1379

Merged
merged 7 commits into from
Dec 23, 2022

Conversation

Shaikh-Ubaid
Copy link
Collaborator

Example:

def Main0():
    x: i32
    x = (2+3)* (-5)
    y: i32 = 100
    z: i32 = 2147483647
    w: i32 = -2147483648
    print(x)
    print(y)
    print(z)
    print(w)
    print("Hi")
    print("Hello")
    print((5-2) * 7)
    print("Bye")

Main0()

Binary Output:

(lp) lpython$ lpython integration_tests/print_03.py  --backend wasm_x64 -o tmp
(lp) lpython$ ./tmp
-25
100
2147483647
-2147483648
Hi
Hello
21
Bye
(lp) lpython$ 

Text Format Output:

(wasm_asm) lpython$ nasm -fbin ./main.asm && chmod +x main && ./main
-25
100
2147483647
-2147483648
Hi
Hello
21
Bye
(wasm_asm) lpython$ 

@Shaikh-Ubaid
Copy link
Collaborator Author

This is ready. Please possibly review and please share feedback.

m_a.asm_mov_r64_imm64(X64Reg::rax, 60); // sys_exit
m_a.asm_syscall(); // syscall
m_a.asm_call_label("print_i64");
m_a.asm_pop_r64(X64Reg::r15); // pop the passed argument
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After this is merged, let's document what the "calling convention" is. It looks like the caller is responsible to put arguments on stack, as well as removing them from stack once the called function (print_i64 in this case) finishes?

Copy link
Collaborator Author

@Shaikh-Ubaid Shaikh-Ubaid Dec 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the caller is responsible to put arguments on stack.

In wasm, the arguments are used up by the called function (that is there is no need to explicitly remove them).

In assembly x86 and/or x64, we are currently manually/explicitly removing the passed arguments in the visit_Call() function:

void visit_Call(uint32_t func_idx) {
if (func_idx <= 6U) {
call_imported_function(func_idx);
return;
}
func_idx -= 7u; // adjust function index as per imports
m_a.asm_call_label(exports[func_idx].name);
// Pop the passed function arguments
wasm::FuncType func_type = func_types[type_indices[func_idx]];
for (uint32_t i = 0; i < func_type.param_types.size(); i++) {
m_a.asm_pop_r64(X64Reg::rax);
}
// Adjust the return values of the called function
X64Reg base = X64Reg::rsp;
for (uint32_t i = 0; i < func_type.result_types.size(); i++) {
// take value into eax
m_a.asm_mov_r64_m64(X64Reg::rax, &base, nullptr, 1,
-8 * (func_type.param_types.size() + 2 +
codes[func_idx].locals.size() + 1));
// push eax value onto stack
m_a.asm_push_r64(X64Reg::rax);
}
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the print_i64, as it is an imported function and as this is an initial support, we are removing the passed arguments just after the call:

void call_imported_function(uint32_t func_idx) {
switch (func_idx) {
case 0: { // print_i32
m_a.asm_call_label("print_i64");
m_a.asm_pop_r64(X64Reg::r15); // pop the passed argument
break;
}

Copy link
Contributor

@certik certik Dec 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should follow the WASM convention and the function should remove them, so in this case print_i64 should remove the arguments from stack. What do you think?

I opened up an issue so that we do not forget: #1381

Copy link
Contributor

@certik certik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks great! Thanks for this.

@certik certik merged commit 7aaedcc into lcompilers:main Dec 23, 2022
@Shaikh-Ubaid Shaikh-Ubaid deleted the wasm_x64_print_ints branch December 23, 2022 23:13
@Shaikh-Ubaid
Copy link
Collaborator Author

Thank you for the approval and merging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants