diff --git a/go/analysis/passes/asmdecl/asmdecl.go b/go/analysis/passes/asmdecl/asmdecl.go index 6e7a76e8c8..c2e89ee2dc 100644 --- a/go/analysis/passes/asmdecl/asmdecl.go +++ b/go/analysis/passes/asmdecl/asmdecl.go @@ -661,6 +661,10 @@ func asmCheckVar(badf func(string, ...interface{}), fn *asmFunc, line, expr stri src = 4 break } + if op == "MOVO" || op == "MOVOU" { + src = 16 + break + } if strings.HasPrefix(op, "SET") { // SETEQ, etc src = 1 @@ -736,6 +740,11 @@ func asmCheckVar(badf func(string, ...interface{}), fn *asmFunc, line, expr stri vk = v.inner[0].kind vs = v.inner[0].size vt = v.inner[0].typ + case asmComplex: + // Allow a single instruction to load both parts of a complex. + if int(kind) == vs { + kind = asmComplex + } } if addr { vk = asmKind(archDef.ptrSize) diff --git a/go/analysis/passes/asmdecl/testdata/src/a/asm1.s b/go/analysis/passes/asmdecl/testdata/src/a/asm1.s index 9af8612277..b39130f149 100644 --- a/go/analysis/passes/asmdecl/testdata/src/a/asm1.s +++ b/go/analysis/passes/asmdecl/testdata/src/a/asm1.s @@ -228,7 +228,6 @@ TEXT ·argiface(SB),0,$0-32 TEXT ·argcomplex(SB),0,$24 // want `wrong argument size 0; expected \$\.\.\.-24` MOVSS x+0(FP), X0 // want `invalid MOVSS of x\+0\(FP\); complex64 is 8-byte value containing x_real\+0\(FP\) and x_imag\+4\(FP\)` - MOVSD x+0(FP), X0 // want `invalid MOVSD of x\+0\(FP\); complex64 is 8-byte value containing x_real\+0\(FP\) and x_imag\+4\(FP\)` MOVSS x_real+0(FP), X0 MOVSD x_real+0(FP), X0 // want `invalid MOVSD of x_real\+0\(FP\); real\(complex64\) is 4-byte value` MOVSS x_real+4(FP), X0 // want `invalid offset x_real\+4\(FP\); expected x_real\+0\(FP\)` @@ -242,6 +241,13 @@ TEXT ·argcomplex(SB),0,$24 // want `wrong argument size 0; expected \$\.\.\.-24 MOVSS y_imag+16(FP), X0 // want `invalid MOVSS of y_imag\+16\(FP\); imag\(complex128\) is 8-byte value` MOVSD y_imag+16(FP), X0 MOVSS y_imag+24(FP), X0 // want `invalid offset y_imag\+24\(FP\); expected y_imag\+16\(FP\)` + // Loading both parts of a complex is ok: see issue 35264. + MOVSD x+0(FP), X0 + MOVO y+8(FP), X0 + MOVOU y+8(FP), X0 + // These are not ok. + MOVO x+0(FP), X0 // want `invalid MOVO of x\+0\(FP\); complex64 is 8-byte value containing x_real\+0\(FP\) and x_imag\+4\(FP\)` + MOVOU x+0(FP), X0 // want `invalid MOVOU of x\+0\(FP\); complex64 is 8-byte value containing x_real\+0\(FP\) and x_imag\+4\(FP\)` RET TEXT ·argstruct(SB),0,$64 // want `wrong argument size 0; expected \$\.\.\.-24`