You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In order to move a 32-bit value from memory into an SSE register, as discussed in this issue, the Go assembler requires the use of MOVL (which is different than the intel/at&t syntax which uses MOVD and chooses based on the source operand).
Go will do a 64-bit load with MOVD despite being a pointer to a 32-bit value. However, avo complains about bad operands when using MOVL since it's not marked as one of its accepted forms.
Here is a minimal example to show the incorrect behavior of MOVD and that MOVL is indeed the correct opcode:
foo.go:
//go:build ignore
package main
import (
"github.com/mmcloughlin/avo/attr"
. "github.com/mmcloughlin/avo/build"
)
func main() {
TEXT("foo", attr.NOSPLIT, "func(n *uint32, out *[16]byte)")
Pragma("noescape")
n, _ := Dereference(Param("n")).Resolve()
r := XMM()
MOVD(n.Addr, r)
out, _ := Dereference(Param("out")).Index(0).Resolve()
MOVOU(r, out.Addr)
RET()
Generate()
}
main.go:
//go:generate go run foo.go -out foo_amd64.s -stubs foo_amd64.go -pkg main
package main
import "fmt"
func main() {
n := uint32(0xaaaaaaaa)
var out [16]byte
foo(&n, &out)
fmt.Printf("%032x\n", out)
}
$ go generate
$ go build && ./issue
aaaaaaaa9854c3000000000000000000 # notice the junk because it moved 64 bits
$ sed -i 's/MOVD/MOVL/' foo_amd64.s # replace MOVD with MOVL in generated asm
$ go build && ./issue
aaaaaaaa000000000000000000000000 # correct result
It's also pretty evident in looking at the compiled code that the first case using MOVD generates an incorrect MOVQ:
The text was updated successfully, but these errors were encountered:
davecgh
changed the title
MOVL should allow XMM registers as a destination.
Bug in avo -- MOVL should allow XMM registers as a destination.
Jun 25, 2024
In order to move a 32-bit value from memory into an SSE register, as discussed in this issue, the Go assembler requires the use of
MOVL
(which is different than the intel/at&t syntax which usesMOVD
and chooses based on the source operand).Go will do a 64-bit load with
MOVD
despite being a pointer to a 32-bit value. However, avo complains about bad operands when usingMOVL
since it's not marked as one of its accepted forms.Here is a minimal example to show the incorrect behavior of
MOVD
and thatMOVL
is indeed the correct opcode:foo.go
:main.go
:It's also pretty evident in looking at the compiled code that the first case using
MOVD
generates an incorrectMOVQ
:Whereas
MOVL
generates the correctMOVD
:The text was updated successfully, but these errors were encountered: