hiya. i have some code that is building a little ffi argument adapter. one thing it does is handle that i8/i16 values have to be represented as i32 by the caller, so i insert ireduce on arguments and uextend/sextend on return values. this doesn't seem to be producing the expected result on aarch64 though, for example passing 256
through the adapter reducing to i8
i would expect to get 0
out, but i get 256
. I don't know the specifics of arm64 but it behaves kind of like if you chose the wrong register size for mov
in x64. Unfortunately I don't have an aarch64 machine so I've just been trying to debug it through CI, so I'm hoping someone here might know where the problem is. Here's the code in question: <https://github.com/denoland/deno/blob/725744955123bf63f22090e4117eec8280fa0d4b/ext/ffi/turbocall.rs#L30-L180>
actually i guess for this specific case, extend isn't even used.
function u0:0(i64, i32) -> i32 system_v {
sig0 = (i8) -> i32 system_v
block0(v0: i64, v1: i32):
v3 = ireduce.i8 v1
v4 = iconst.i64 0x7fe3_dc66_b090
v5 = call_indirect sig0, v4(v3)
return v5
}
Apple's arm64 calling convention requires zero/sign extending integer arguments smaller than 32bit. You can use ArgumentExtension::Uext/Sext
in the AbiParam
of the function signature for this.
The caller of a function is responsible for signing or zero-extending any argument with fewer than 32 bits. The standard ABI expects the callee to sign or zero-extend those arguments.
ooo perfect, ty! is it safe to just set this extension on all the int types as informed by their signedness?
Yes, though for 32bit integers it would add some unnecessary overhead.
oh like it will still insert extension instructions?
I suspect it does. I haven't checked though.
Last updated: Feb 27 2025 at 23:03 UTC