Compiler explorer link: https://zig.godbolt.org/z/KvG5h3
Zig code involved:
const std = @import("std");
pub fn main() !void {
testcall(true);
return;
}
export fn testcall(t: bool) void {
asm volatile("" : : [_] "{rbx}" (@as(u64,0x1122334455667788)) : "memory" ); // clobber rbx with garbage to not give it a chance
asm volatile(
\\push %%rbx
\\pop %%rdi
\\call stage2
:
: [_] "{rbx}" (@boolToInt(t))
: "memory"
);
}
export fn stage2(param: usize) void {
std.debug.warn("param: {x}", .{param});
}
What's the problem? Well, let's look at the code zig compiler from trunk gave us:
testcall:
push rbx
movabs rbx, 1234605616436508552; clobber rbx with garbage to not give it a chance
; That's how rbx is assigned to 1
and dil, 1
mov ebx, edi
; End of assignment
push rbx ; That is where our asm volatile code starts
pop rdi
call stage2
pop rbx
ret
Zig compiler generates code that only makes the lowest bit of rbx set. The problem is that the code explicitly demands that the compiler generates code assigning one to the rbx, meaning that the value of rbx should be one, while if you run this example in compiler explorer, it will give you a different result.
Cast to u64 indeed solve the problem, however, this case is either 1) an incorrect behavior that should be patched 2) correct behavior that needs to be clarified (so that there is a requirement that code inside volatile asm block will only use rdi as u1, and not as usize as here)
Compiler explorer link: https://zig.godbolt.org/z/KvG5h3
Zig code involved:
What's the problem? Well, let's look at the code zig compiler from trunk gave us:
Zig compiler generates code that only makes the lowest bit of rbx set. The problem is that the code explicitly demands that the compiler generates code assigning one to the rbx, meaning that the value of rbx should be one, while if you run this example in compiler explorer, it will give you a different result.
Cast to u64 indeed solve the problem, however, this case is either 1) an incorrect behavior that should be patched 2) correct behavior that needs to be clarified (so that there is a requirement that code inside volatile asm block will only use rdi as u1, and not as usize as here)