mmcloughlin / avo

Generate x86 Assembly with Go
BSD 3-Clause "New" or "Revised" License
2.69k stars 89 forks source link

proposal: return destination register from `build` functions #194

Open dominikh opened 3 years ago

dominikh commented 3 years ago

I propose that the functions in package build return the destination register, where it makes sense. This would be especially useful in the context of AVX/VEX encoding and the 3 argument form (with the destination register separate from the operands) and would allow writing code like this:

v1 := VMOVDQU(m1, YMM())
v2 := VMOVDQU(m2, YMM())
res := VPSUBB(v1, v2, YMM())

or even like this, if the loaded values don't need to be used again

res := VPSUBB(
  VMOVDQU(m1, YMM()), 
  VMOVDQU(m2, YMM()),
  YMM())

instead of

v1 := YMM()
v2 := YMM()
v3 := YMM()
VMOVDQU(m1, v1)
VMOVDQU(m2, v2)
VPSUBB(v1, v2, v3)

or the manually optimized version, which isn't necessary due to avo's register allocator, but still results in shorter Go code currently:

v1 := YMM()
v2 := YMM()
VMOVDQU(m1, v1)
VMOVDQU(m2, v2)
VPSUBB(v1, v2, v1)

There is some precedent for this, namely the Load function, which already returns the destination register.

mmcloughlin commented 3 years ago

Thanks for the proposal! I'd need to think about it a bit more, but my initial reaction is that this could a be really nice addition.