Well there's more asm I'm writing now around it - sorry just figuring out how this works myself.
I'm basically making a trampoline (? I think that's a standard way to name this) for a sort of compiler I'm writing for fun.
For now I'm just putting all args & results on the stack, and sort of say that all registers are caller saved. That's the easiest thing for me to do.
I have this now:
noinline fn trampoline(func_info: FuncInfo, args: [*]const u8, result: [*]u8) void {
const arg_bytes: u64 = @intCast(func_info.arg_byte_size + func_info.res_byte_size);
const res_bytes: u64 = @intCast(func_info.res_byte_size);
const addr: u64 = @intCast(func_info.jump_address);
asm volatile (
\\ mov %[arg_bytes], %[temp_data]
\\ sub %[temp_data], %%rsp
\\ mov %[temp_data], %[counter]
\\ mov %[res_bytes], %[temp_data]
\\ sub %[temp_data], %%rsp
\\ shrq $2, %[counter]
\\ xor %[index], %[index]
\\ arg_loop:
\\ mov 0(%[args],%[index],8), %[temp_data]
\\ mov %[temp_data], 0(%%rsp,%[index],8)
\\ inc %[index]
\\ dec %[counter]
\\ jnz arg_loop
\\ call *%[addr]
\\ mov %[res_bytes], %[counter]
\\ shrq $2, %[counter]
\\ xor %[index], %[index]
\\ res_loop:
\\ mov 0(%%rsp,%[index],8), %[temp_data]
\\ mov %[temp_data], 0(%[result],%[index],8)
\\ inc %[index]
\\ dec %[counter]
\\ jnz res_loop
\\ mov %[res_bytes], %[temp_data]
\\ add %[temp_data], %%rsp
:
: [res_bytes] "m" (res_bytes),
[arg_bytes] "m" (arg_bytes),
[addr] "r" (addr),
[args] "r" (args),
[result] "r" (result),
[counter] "r" (0),
[index] "r" (0),
[temp_data] "r" (0),
: "memory", "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" // TODO: Add FP & Vector registers here
);
}
Which I think should be correct in general (of course not super sure about the ASM, I'm new to it, especially the stupid AT&T syntax...)
I just haven't really figured out the clobbers part - I think it shuold be correct declaring it like this (-> these are the registers I might allocate internally), and the memory clobber is right too I think?
Problem is that of course there are no registers left for llvm to assign to my inputs - it just error: inline assembly requires more registers than available.
Not sure how I can allow inputs to also be clobbers.
Is this the right way to achieve what I'm trying to? Or is there some other way I could do this?