#How to Declare a Variable that Aliases a Register

1 messages · Page 1 of 1 (latest)

elfin acorn
#

I'm currently building a virtual machine, and I want to essentially perform conditional compilation to improve performance on certain architectures.

Is there a way to mix variable declaration and inline asm syntax to declare a variable that aliases a specific register? This way I can reuse code that reads from the variables, and would only incur the cost of writing per-target code when I declare the variables.

naive lava
#

does it need to be in the same register before and after the asm block? if so, why?

elfin acorn
#

It's a sort of "register-pinning".

woven cedar
#

i don't think it's possible to require zig variables to go in certain registers, but if you e.g.

  • const foo = asm(...) with an output constraint that the result of the asm block is in some register (let's say rax)
  • later pass foo into another asm block and specify as an input constraint that foo should go into rax
    i imagine the register allocator may smile upon you and decide to keep foo in rax throughout the zig code in between those asm blocks
#

i'd be curious to godbolt this actually

#

but also, even if foo gets moved to another register and back in between the asm blocks... i'm not sure how much that would really penalize you on a modern cpu core with register renaming

#

because it could alias to the same physical register even if it gets moved to a different ISA register

elfin acorn
#

Plus (in your example) I wouldn't be able to prevent registers from being clobbered without incurring a significant performance penalty. At this point I should probably just make an IR rather than a virtual machine. TBH, I'm not really sure what I was thinking.

night citrus
#

@elfin acorn I skinned a similar cat by using callconv(.SysV) then relying on the guarantees that calling convention offers regarding what registers are used to pass function parameters. Note that I was building a threaded interpreter (so not exactly a virtual machine but close). Would that help your specific case? See https://bur.gy/2024/08/31/why-not-zig.html if you'd like to know more

woven cedar
#

even with a forced callconv zig might move parameters into a different register if it feels like it

night citrus
#

Are you saying callconv is just a hint that zig is free to ignore? That's unexpected. FWIW, zig did respect the rdi, rsi, rdx, r10, r8, r9 when it compiled my code.

woven cedar
#

i'm saying that in

fn foo(x: i64) callconv(.SysV) {
    // ...
}

x may not be in rdi throughout the entire execution of foo

#

e.g. if it calls another function it'll have to move x to a saved register or the stack, and it probably won't set rdi back to x after that function returns

#

if you have assembly that relies on rdi holding the value of x you need an input constraint to specify that