[x86-64] Passing a 128-bit integer to a C function using CCALL
Passing a 128-bit integer to a C function (ussing CCALL) dosn't work on x86-64, e.g: I wrote a test to check that 128-bit integers are passed correctly when calling functions (it is designed to cause the last argument to be placed on the stack on x86, but on aarch64 it should be in a register).
arg_overflow.uir:
.funcsig test_arg_overflow_sig = () -> ()
.funcdef my_main<()->()>
{
entry():
CCALL #DEFAULT <ufuncptr<test_arg_overflow_sig> test_arg_overflow_sig> <ufuncptr<test_arg_overflow_sig>>EXTERN "c_test_arg_overflow" ()
CALL <test_arg_overflow_sig> mu_test_arg_overflow()
RET
}
.funcsig arg_overflow_sig = (int<64> int<128> int<128> int<128>) -> ()
.funcdef mu_test_arg_overflow<test_arg_overflow_sig>
{
entry():
int128_0 = ADD <int<128>> <int<128>>0 <int<128>>0
int128_F = ADD <int<128>> <int<128>>0 <int<128>>0xFFFFFFFFFFFFFFFF0000000000000000
CCALL #DEFAULT <ufuncptr<arg_overflow_sig> arg_overflow_sig> <ufuncptr<arg_overflow_sig>>EXTERN "arg_overflow" (<int<64>>0 int128_0 int128_0 int128_F)
RET
}
It needs to be compiled with the following C code: arg_overflow.c
#include <stdint.h>
#include <stdio.h>
void arg_overflow(uint64_t a, __int128_t b, __int128_t c, __int128_t d) {
printf("d = %016lX%016lX\n", (uint64_t)(d >> 64), (uint64_t)d);
}
void c_test_arg_overflow()
{
arg_overflow(0, 0, 0, (__int128_t)(0xFFFFFFFFFFFFFFFF) << 64);
}
On x86-64 using the line ./muc -r -f my_main arg_overflow.uir arg_overflow/arg_overflow
, (using the latest commit in the aarch64 branch) it fails to compile, giving the error:
thread '<unnamed>' panicked at 'not yet implemented', src/compiler/backend/arch/x86_64/inst_sel.rs:3181
stack backtrace:
0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
1: std::sys_common::backtrace::_print
at /checkout/src/libstd/sys_common/backtrace.rs:71
2: std::panicking::default_hook::{{closure}}
at /checkout/src/libstd/sys_common/backtrace.rs:60
at /checkout/src/libstd/panicking.rs:355
3: std::panicking::default_hook
at /checkout/src/libstd/panicking.rs:371
4: std::panicking::rust_panic_with_hook
at /checkout/src/libstd/panicking.rs:549
5: std::panicking::begin_panic
6: mu::compiler::backend::x86_64::inst_sel::InstructionSelection::emit_c_call_ir
7: mu::compiler::backend::x86_64::inst_sel::InstructionSelection::instruction_select
8: <mu::compiler::backend::x86_64::inst_sel::InstructionSelection as mu::compiler::passes::CompilerPass>::visit_function
9: mu::compiler::passes::CompilerPass::execute
10: mu::compiler::Compiler::compile
11: mu::vm::vm::VM::make_boot_image_internal
12: mu::vm::api::api_bridge::_forwarder__MuCtx__make_boot_image
13: main
14: __libc_start_main
15: _start
fatal runtime error: failed to initiate panic, error 5
Aborted (core dumped)
On aarch64 it compiles (well Zebu fails at linking, but it works if I add 'arg_overflow.c' to the clang command) and runs correctly, printing:
d = FFFFFFFFFFFFFFFF0000000000000000
d = FFFFFFFFFFFFFFFF0000000000000000