diff --git a/amd64_ctx.go b/amd64_ctx.go index 03abb4ab..3eeef7ed 100644 --- a/amd64_ctx.go +++ b/amd64_ctx.go @@ -31,8 +31,9 @@ type amd64Ctx struct { usedRegs map[Reg]bool regSlot map[Reg]string // gp reg -> alloca name - usedXRegs map[int]bool - xRegSlot map[int]string // xmm reg index -> alloca name (<16 x i8>) + zeroUpperVector bool // VEX/EVEX writes clear the upper register bits + usedXRegs map[int]bool + xRegSlot map[int]string // xmm reg index -> alloca name (<16 x i8>) usedYRegs map[int]bool yRegSlot map[int]string // ymm reg index -> alloca name (<32 x i8>) @@ -334,40 +335,41 @@ func (c *amd64Ctx) emitEntryAllocas() error { fmt.Fprintf(c.b, " store i64 %%%s, ptr %s\n", addr, spSlot) } - xIdx := make([]int, 0, len(c.usedXRegs)) + // XMM, YMM and ZMM are overlapping views of the same physical register. + // Allocate the widest view used by the function and share its low bytes. + widths := make(map[int]int) for i := range c.usedXRegs { - xIdx = append(xIdx, i) + widths[i] = 16 } - sort.Ints(xIdx) - for _, i := range xIdx { - name := c.xSlotName(i) - c.xRegSlot[i] = name - fmt.Fprintf(c.b, " %s = alloca <16 x i8>\n", name) - fmt.Fprintf(c.b, " store <16 x i8> zeroinitializer, ptr %s\n", name) - } - - yIdx := make([]int, 0, len(c.usedYRegs)) for i := range c.usedYRegs { - yIdx = append(yIdx, i) - } - sort.Ints(yIdx) - for _, i := range yIdx { - name := fmt.Sprintf("%%y%d", i) - c.yRegSlot[i] = name - fmt.Fprintf(c.b, " %s = alloca <32 x i8>\n", name) - fmt.Fprintf(c.b, " store <32 x i8> zeroinitializer, ptr %s\n", name) + widths[i] = 32 } - - zIdx := make([]int, 0, len(c.usedZRegs)) for i := range c.usedZRegs { - zIdx = append(zIdx, i) + widths[i] = 64 + } + indices := make([]int, 0, len(widths)) + for i := range widths { + indices = append(indices, i) } - sort.Ints(zIdx) - for _, i := range zIdx { - name := fmt.Sprintf("%%z%d", i) - c.zRegSlot[i] = name - fmt.Fprintf(c.b, " %s = alloca <64 x i8>\n", name) - fmt.Fprintf(c.b, " store <64 x i8> zeroinitializer, ptr %s\n", name) + sort.Ints(indices) + for _, i := range indices { + width := widths[i] + name := c.xSlotName(i) + if width == 32 { + name = fmt.Sprintf("%%y%d", i) + } + if width == 64 { + name = fmt.Sprintf("%%z%d", i) + } + c.xRegSlot[i] = name + if width >= 32 { + c.yRegSlot[i] = name + } + if width == 64 { + c.zRegSlot[i] = name + } + fmt.Fprintf(c.b, " %s = alloca <%d x i8>\n", name, width) + fmt.Fprintf(c.b, " store <%d x i8> zeroinitializer, ptr %s\n", width, name) } kIdx := make([]int, 0, len(c.usedKRegs)) @@ -998,6 +1000,21 @@ func (c *amd64Ctx) storeRegSized(r Reg, ty LLVMType, v string) error { } } +// clearVectorUpper clears bytes above the written width while leaving the +// low view unchanged. Legacy SSE writes deliberately preserve those bytes. +func (c *amd64Ctx) clearVectorUpper(idx, lowBytes int) { + slot, width := c.zRegSlot[idx], 64 + if slot == "" { + slot, width = c.yRegSlot[idx], 32 + } + if slot == "" || width <= lowBytes { + return + } + upper := c.newTmp() + fmt.Fprintf(c.b, " %%%s = getelementptr i8, ptr %s, i64 %d\n", upper, slot, lowBytes) + fmt.Fprintf(c.b, " store <%d x i8> zeroinitializer, ptr %%%s, align 1\n", width-lowBytes, upper) +} + func (c *amd64Ctx) loadX(r Reg) (string, error) { idx, ok := amd64ParseXReg(r) if !ok { @@ -1021,6 +1038,9 @@ func (c *amd64Ctx) storeX(r Reg, v string) error { if !ok { return nil } + if c.zeroUpperVector { + c.clearVectorUpper(idx, 16) + } fmt.Fprintf(c.b, " store <16 x i8> %s, ptr %s\n", v, slot) return nil } @@ -1048,6 +1068,9 @@ func (c *amd64Ctx) storeY(r Reg, v string) error { if !ok { return nil } + if c.zeroUpperVector { + c.clearVectorUpper(idx, 32) + } fmt.Fprintf(c.b, " store <32 x i8> %s, ptr %s\n", v, slot) return nil } diff --git a/amd64_lower_vec.go b/amd64_lower_vec.go index a4c111a6..ebfb7a52 100644 --- a/amd64_lower_vec.go +++ b/amd64_lower_vec.go @@ -111,11 +111,16 @@ func (c *amd64Ctx) lowerVec(op Op, ins Instr) (ok bool, terminated bool, err err } } - if op == "VZEROUPPER" { - // No-op in LLVM IR. Kept for completeness. - return true, false, nil - } - if op == "VZEROALL" { + if op == "VZEROUPPER" || op == "VZEROALL" { + // These instructions affect registers 0-15, including their ZMM view. + for i := 0; i < 16; i++ { + c.clearVectorUpper(i, 16) + if op == "VZEROALL" { + if slot := c.xRegSlot[i]; slot != "" { + fmt.Fprintf(c.b, " store <16 x i8> zeroinitializer, ptr %s\n", slot) + } + } + } return true, false, nil } diff --git a/amd64_translate.go b/amd64_translate.go index 64ae5abe..1439e683 100644 --- a/amd64_translate.go +++ b/amd64_translate.go @@ -241,6 +241,7 @@ func (c *amd64Ctx) lowerInstr(bi int, ii int, ins Instr, emitBr amd64EmitBr, emi c.allowSPWrite = models386SPWrite(ins) defer func() { c.allowSPWrite = false }() op := strings.ToUpper(string(ins.Op)) + c.zeroUpperVector = strings.HasPrefix(op, "V") if c.repeatPrefix != "" && op != "MOVSB" && op != "MOVSL" && op != "STOSL" && op != "SCASB" { prefix := c.repeatPrefix c.repeatPrefix = "" diff --git a/amd64_vector_alias_test.go b/amd64_vector_alias_test.go new file mode 100644 index 00000000..797ffc41 --- /dev/null +++ b/amd64_vector_alias_test.go @@ -0,0 +1,58 @@ +//go:build !llgo + +package plan9asm + +import ( + "fmt" + "runtime" + "testing" +) + +func TestAMD64VectorRegisterAliases(t *testing.T) { + crossRosetta := runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" && rosettaAvailable() + if runtime.GOARCH != "amd64" && !crossRosetta { + t.Skip("requires amd64 execution") + } + llc, clang, ok := findLlcAndClang(t) + if !ok { + t.Skip("llc/clang not found") + } + triple := testTargetTriple(runtime.GOOS, "amd64") + var prefix []string + if crossRosetta { + prefix = []string{"/usr/bin/arch", "-x86_64"} + } + for _, tc := range []struct{ name, instructions, expected string }{ + {"wide_to_narrow", "VMOVDQU64 (SI), Z1\nMOVOU X1, (DI)", "i < 16 ? in[i] : 0"}, + {"legacy_preserves_upper", "VMOVDQU64 (SI), Z1\nMOVOU 64(SI), X1\nVMOVDQU64 Z1, (DI)", "i < 16 ? in[64+i] : in[i]"}, + {"vex128_clears_upper", "VMOVDQU64 (SI), Z1\nMOVOU 64(SI), X2\nVMOVAPS X2, X1\nVMOVDQU64 Z1, (DI)", "i < 16 ? in[64+i] : 0"}, + {"vex256_clears_upper", "VMOVDQU64 (SI), Z1\nVMOVDQU 64(SI), Y1\nVMOVDQU64 Z1, (DI)", "i < 32 ? in[64+i] : 0"}, + {"zero_upper", "VMOVDQU64 (SI), Z1\nVZEROUPPER\nVMOVDQU64 Z1, (DI)", "i < 16 ? in[i] : 0"}, + {"zero_all", "VMOVDQU64 (SI), Z1\nVZEROALL\nVMOVDQU64 Z1, (DI)", "0"}, + } { + t.Run(tc.name, func(t *testing.T) { + source := "TEXT probe(SB),NOSPLIT,$0-16\nMOVQ in+0(FP), SI\nMOVQ out+8(FP), DI\n" + tc.instructions + "\nRET\n" + file, err := Parse(ArchAMD64, source) + if err != nil { + t.Fatal(err) + } + ll, err := Translate(file, Options{TargetTriple: triple, Goarch: "amd64", Sigs: map[string]FuncSig{"probe": {Name: "probe", Args: []LLVMType{Ptr, Ptr}, Ret: Void, Frame: FrameLayout{Params: []FrameSlot{{Offset: 0, Type: Ptr, Index: 0, Field: -1}, {Offset: 8, Type: Ptr, Index: 1, Field: -1}}}}}}) + if err != nil { + t.Fatal(err) + } + mainC := fmt.Sprintf(`#include +extern void probe(unsigned char *, unsigned char *); +int main(void) { + unsigned char in[128], out[64] = {0}; + for (int i = 0; i < 128; ++i) in[i] = (unsigned char)(i + 1); + probe(in, out); + for (int i = 0; i < 64; ++i) { + unsigned char want = %s; + if (out[i] != want) { fprintf(stderr, "byte %%d: got %%u, want %%u\n", i, out[i], want); return 1; } + } + return 0; +}`, tc.expected) + compileAndRunRuntimeTestForTarget(t, llc, clang, "vector_alias", triple, ll, mainC, prefix) + }) + } +} diff --git a/arm64_conformance_test.go b/arm64_conformance_test.go index 87680aa8..940c2c3b 100644 --- a/arm64_conformance_test.go +++ b/arm64_conformance_test.go @@ -51,6 +51,15 @@ func translateARM64Conformance(t *testing.T, triple string) string { ResolveSym: func(sym string) string { return strings.TrimPrefix(sym, "·") }, Goarch: "arm64", Sigs: map[string]FuncSig{ + "pairStores": { + Name: "pairStores", + Args: []LLVMType{Ptr, Ptr}, + Ret: Void, + Frame: FrameLayout{Params: []FrameSlot{ + {Offset: 0, Type: Ptr, Index: 0, Field: -1}, + {Offset: 8, Type: Ptr, Index: 1, Field: -1}, + }}, + }, "families": { Name: "families", Args: []LLVMType{Ptr, Ptr}, @@ -96,6 +105,8 @@ func TestARM64ConformanceLLVMRuntime(t *testing.T) { mainC := ` #include extern void families(uint64_t *out, uint64_t *data); +extern void pairStores(uint64_t *out, uint64_t *data); +uint64_t pairStoreData[10]; int main(void) { uint64_t data[8] = {0x0123456789abcdefULL, 0xfedcba9876543210ULL, 0x1122334455667788ULL, 0x8877665544332211ULL}; uint64_t want[76] = { @@ -121,6 +132,26 @@ int main(void) { for (int i = 0; i < 76; i++) if (got[i] != want[i]) return i + 1; + uint64_t pairs[20], expected[20]; + for (int i = 0; i < 20; i++) + pairs[i] = expected[i] = 0xdeadbeef; + expected[0] = 0; + expected[1] = 32; + expected[6] = (uint64_t)-32; + for (int i = 0; i < 4; i++) { + expected[2 + i] = expected[16 + i] = data[i]; + expected[8 + i] = data[(i + 2) % 4]; + } + for (int i = 0; i < 10; i++) + pairStoreData[i] = 0xdeadbeef; + pairStores(pairs, data); + for (int i = 0; i < 20; i++) + if (pairs[i] != expected[i]) + return 100 + i; + uint64_t symbolExpected[10] = {data[0], data[1], data[2], data[3], 0xdeadbeef, data[2], data[3], data[0], data[1], 0xdeadbeef}; + for (int i = 0; i < 10; i++) + if (pairStoreData[i] != symbolExpected[i]) + return 120 + i; return 0; } ` diff --git a/arm64_lower_vec.go b/arm64_lower_vec.go index e6282336..d4c803f3 100644 --- a/arm64_lower_vec.go +++ b/arm64_lower_vec.go @@ -93,6 +93,40 @@ func (c *arm64Ctx) lowerVec(op Op, postInc bool, ins Instr) (ok bool, terminated return true, false, fmt.Errorf("arm64 FMOVQ expects memory and F register operands: %q", ins.Raw) } + case "FSTPQ": + if len(ins.Args) != 2 || ins.Args[0].Kind != OpRegList || len(ins.Args[0].RegList) != 2 || (ins.Args[1].Kind != OpMem && ins.Args[1].Kind != OpSym) { + return true, false, fmt.Errorf("arm64 FSTPQ expects (Freg,Freg), mem: %q", ins.Raw) + } + for _, f := range ins.Args[0].RegList { + if _, ok := arm64ParseFReg(f); !ok { + return true, false, fmt.Errorf("arm64 FSTPQ expects FP register pair: %q", ins.Raw) + } + } + preInc := strings.Contains(strings.ToUpper(string(ins.Op)), ".W") + ptr, base, inc, update, err := c.arm64VectorMemoryPointer(ins.Args[1], preInc, postInc) + if err != nil { + return true, false, err + } + for i, f := range ins.Args[0].RegList { + value, err := c.loadVReg(f) + if err != nil { + return true, false, err + } + storePtr := ptr + if i != 0 { + next := c.newTmp() + fmt.Fprintf(c.b, " %%%s = getelementptr i8, ptr %s, i64 16\n", next, ptr) + storePtr = "%" + next + } + fmt.Fprintf(c.b, " store <16 x i8> %s, ptr %s, align 1\n", value, storePtr) + } + if update { + if err := c.updatePostInc(base, inc); err != nil { + return true, false, err + } + } + return true, false, nil + case "FLDPQ": if len(ins.Args) != 2 || ins.Args[0].Kind != OpMem || ins.Args[1].Kind != OpRegList || len(ins.Args[1].RegList) != 2 { return true, false, fmt.Errorf("arm64 FLDPQ expects mem, (Freg,Freg): %q", ins.Raw) diff --git a/testdata/conformance/arm64/conformance.go b/testdata/conformance/arm64/conformance.go index 982ca64c..98b17b0e 100644 --- a/testdata/conformance/arm64/conformance.go +++ b/testdata/conformance/arm64/conformance.go @@ -3,3 +3,7 @@ package arm64conformance func families(out *[76]uint64, data *[8]uint64) + +func pairStores(out *[20]uint64, data *[8]uint64) + +var pairStoreData [10]uint64 diff --git a/testdata/conformance/arm64/conformance_arm64.s b/testdata/conformance/arm64/conformance_arm64.s index 0060bff2..331641f1 100644 --- a/testdata/conformance/arm64/conformance_arm64.s +++ b/testdata/conformance/arm64/conformance_arm64.s @@ -185,3 +185,31 @@ TEXT ·families(SB), NOSPLIT, $0-16 FMOVD R2, F4 FMOVQ F4, 592(R0) RET + +// Check full-width stores, offsets, and both writeback modes. +TEXT ·pairStores(SB), NOSPLIT, $0-16 + MOVD out+0(FP), R0 + MOVD data+8(FP), R1 + FMOVQ (R1), F0 + FMOVQ 16(R1), F1 + + MOVD R0, R2 + FSTPQ (F0, F1), 16(R2) + SUB R0, R2, R3 + MOVD R3, (R0) + + ADD $64, R0, R2 + MOVD R2, R4 + FSTPQ.P (F1, F0), 32(R2) + SUB R4, R2, R3 + MOVD R3, 8(R0) + + ADD $160, R0, R2 + MOVD R2, R4 + FSTPQ.W (F0, F1), -32(R2) + SUB R4, R2, R3 + MOVD R3, 48(R0) + + FSTPQ (F0, F1), ·pairStoreData(SB) + FSTPQ (F1, F0), ·pairStoreData+40(SB) + RET diff --git a/testdata/conformance/arm64/conformance_test.go b/testdata/conformance/arm64/conformance_test.go index b7b3e3f2..f63d4054 100644 --- a/testdata/conformance/arm64/conformance_test.go +++ b/testdata/conformance/arm64/conformance_test.go @@ -102,3 +102,38 @@ func bool64(value bool) uint64 { } return 0 } + +func TestPairStores(t *testing.T) { + data := [8]uint64{0x0123456789abcdef, 0xfedcba9876543210, 0x1122334455667788, 0x8877665544332211} + var got, want [20]uint64 + for i := range got { + got[i], want[i] = 0xdeadbeef, 0xdeadbeef + } + want[0], want[1], want[6] = 0, 32, ^uint64(31) + copy(want[2:6], data[:4]) + copy(want[8:10], data[2:4]) + copy(want[10:12], data[:2]) + copy(want[16:20], data[:4]) + for i := range pairStoreData { + pairStoreData[i] = 0xdeadbeef + } + pairStores(&got, &data) + for i := range got { + if got[i] != want[i] { + t.Fatalf("pairStores()[%d] = %#x, want %#x", i, got[i], want[i]) + } + } +} + +func TestPairStoreSymbols(t *testing.T) { + data := [8]uint64{0x0123456789abcdef, 0xfedcba9876543210, 0x1122334455667788, 0x8877665544332211} + var out [20]uint64 + for i := range pairStoreData { + pairStoreData[i] = 0xdeadbeef + } + pairStores(&out, &data) + want := [10]uint64{data[0], data[1], data[2], data[3], 0xdeadbeef, data[2], data[3], data[0], data[1], 0xdeadbeef} + if pairStoreData != want { + t.Fatalf("pairStoreData = %#x, want %#x", pairStoreData, want) + } +} diff --git a/testdata/conformance/manifest.json b/testdata/conformance/manifest.json index 9ff737b7..a51f46e1 100644 --- a/testdata/conformance/manifest.json +++ b/testdata/conformance/manifest.json @@ -181,7 +181,9 @@ "FMOVD gpr,floating-register", "FMOVQ memory.gpr-base,floating-register", "FMOVQ memory.gpr-base.offset,floating-register", - "FMOVQ floating-register,memory.gpr-base.offset" + "FMOVQ floating-register,memory.gpr-base.offset", + "FSTPQ register-list,memory.gpr-base.offset", + "FSTPQ register-list,symbol" ] } ] diff --git a/testdata/corpus/go.mod b/testdata/corpus/go.mod index 3fa2be21..afeb8c69 100644 --- a/testdata/corpus/go.mod +++ b/testdata/corpus/go.mod @@ -13,13 +13,13 @@ require ( github.com/dgryski/go-bits v0.0.0-20180113010104-bd8a69a71dc2 github.com/dgryski/go-marvin32 v0.0.0-20240117220238-0d39e8c5a8a9 github.com/golang/snappy v1.0.0 - github.com/klauspost/compress v1.20.0 + github.com/klauspost/compress v1.20.1 github.com/klauspost/cpuid v1.3.1 github.com/klauspost/cpuid/v2 v2.4.0 github.com/klauspost/reedsolomon v1.14.2 github.com/minio/highwayhash v1.0.4 github.com/modern-go/gls v0.0.0-20250215024828-78308f6bb19d - github.com/pierrec/lz4/v4 v4.1.30 + github.com/pierrec/lz4/v4 v4.1.33 github.com/stevvooe/resumable v0.0.0-20180830230917-22b14a53ba50 github.com/tmthrgd/go-bitwise v0.0.0-20190904053232-1430ee983fca github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc diff --git a/testdata/corpus/go.sum b/testdata/corpus/go.sum index 8e7ff470..ac4018eb 100644 --- a/testdata/corpus/go.sum +++ b/testdata/corpus/go.sum @@ -25,6 +25,8 @@ github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/klauspost/compress v1.20.0 h1:a3C1ke2ohxFymNlb2HWAHjDeKCI90scRskErZkR0ezA= github.com/klauspost/compress v1.20.0/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI= +github.com/klauspost/compress v1.20.1 h1:T7kKElXUMXrUJ2E9QhQhxFtcK5rPyLdsGZvdbLMPdiQ= +github.com/klauspost/compress v1.20.1/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI= github.com/klauspost/cpuid v1.3.1 h1:5JNjFYYQrZeKRJ0734q51WCEEn2huer72Dc7K+R/b6s= github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4= github.com/klauspost/cpuid/v2 v2.4.0 h1:S6Hrbc7+ywsr0r+RLapfGBHfyefhCTwEh3A0tV913Dw= @@ -43,6 +45,8 @@ github.com/pierrec/lz4/v4 v4.1.29 h1:CDQY6qZOLI4DW0Nx6R1vRrifrCeQHnNXkMb0hZWXFjg github.com/pierrec/lz4/v4 v4.1.29/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4= github.com/pierrec/lz4/v4 v4.1.30 h1:cchX8N2DVP668WkElI9QMwVyoNabLkq1LofDHFeIrdg= github.com/pierrec/lz4/v4 v4.1.30/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4= +github.com/pierrec/lz4/v4 v4.1.33 h1:GjG1TJ1V4IzKP8L96muuuDNpTwd7D+l2ccXrjAbe014= +github.com/pierrec/lz4/v4 v4.1.33/go.mod h1:7SE9MC2STkNtL4PIwGhjmyVwvILaGI9/COYQNBhKM/c= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= diff --git a/testdata/corpus/reported-libraries.json b/testdata/corpus/reported-libraries.json index b11dcad4..a9ac2484 100644 --- a/testdata/corpus/reported-libraries.json +++ b/testdata/corpus/reported-libraries.json @@ -56,7 +56,7 @@ "https://github.com/xgo-dev/llgo/issues/2552" ], "module": "github.com/klauspost/compress", - "version": "v1.20.0", + "version": "v1.20.1", "inventory": { "darwin/amd64": { "asm_files": 8, @@ -360,11 +360,14 @@ "id": "pierrec-lz4-v4", "origin": "ecosystem-scan", "module": "github.com/pierrec/lz4/v4", - "version": "v4.1.30", + "version": "v4.1.33", "inventory": { "darwin/amd64": { - "asm_files": 1, - "packages": ["github.com/pierrec/lz4/v4/internal/lz4block"] + "asm_files": 3, + "packages": [ + "github.com/pierrec/lz4/v4/internal/lz4block", + "github.com/pierrec/lz4/v4/internal/xxh32" + ] }, "darwin/arm64": { "asm_files": 2, @@ -374,8 +377,11 @@ ] }, "linux/amd64": { - "asm_files": 1, - "packages": ["github.com/pierrec/lz4/v4/internal/lz4block"] + "asm_files": 3, + "packages": [ + "github.com/pierrec/lz4/v4/internal/lz4block", + "github.com/pierrec/lz4/v4/internal/xxh32" + ] }, "linux/arm": { "asm_files": 2, @@ -392,8 +398,11 @@ ] }, "windows/amd64": { - "asm_files": 1, - "packages": ["github.com/pierrec/lz4/v4/internal/lz4block"] + "asm_files": 3, + "packages": [ + "github.com/pierrec/lz4/v4/internal/lz4block", + "github.com/pierrec/lz4/v4/internal/xxh32" + ] }, "windows/arm64": { "asm_files": 2, diff --git a/testdata/coverage/arm64-go-assembler-families.txt b/testdata/coverage/arm64-go-assembler-families.txt index ce14fe95..eb348f8f 100644 --- a/testdata/coverage/arm64-go-assembler-families.txt +++ b/testdata/coverage/arm64-go-assembler-families.txt @@ -1,4 +1,4 @@ -# ARM64 scalar opcode families completed by the issue #2552 fix. +# ARM64 opcode families covered by the Go assembler conformance checks. # The Go assembler encoder tables and positive testdata define this list's # legal operand forms; external packages are regression consumers only. BFI @@ -49,6 +49,7 @@ SUBSW TST TSTW FMOVQ +FSTPQ MOVB MOVBU MOVH diff --git a/testdata/coverage/arm64-xarch-plan9-baseline.json b/testdata/coverage/arm64-xarch-plan9-baseline.json index 9a51f9d7..797bfcf9 100644 --- a/testdata/coverage/arm64-xarch-plan9-baseline.json +++ b/testdata/coverage/arm64-xarch-plan9-baseline.json @@ -6,9 +6,9 @@ "asm_files": 1, "unique_ops": 667, "unique_forms": 1108, - "supported_forms": 379, + "supported_forms": 381, "context_forms": 54, - "unsupported_forms": 675, + "unsupported_forms": 673, "parse_err_count": 0, - "coverage_fingerprint": "9530b87906a6aa540bc57a6011563a79b077baadfad88980da0d53d306e96881" + "coverage_fingerprint": "a71bea198154ac63c55b87085cc0b1e03136ad32b7e0010084d140ee007a8d93" } diff --git a/testdata/coverage/go-asm-baseline.json b/testdata/coverage/go-asm-baseline.json index 12f15ea1..eb580370 100644 --- a/testdata/coverage/go-asm-baseline.json +++ b/testdata/coverage/go-asm-baseline.json @@ -77,14 +77,14 @@ }, "arm64": { "context_forms": 45, - "coverage_fingerprint": "95931d2efbda61ed77dee4878a6d81003e0cca9c8c45cf403801ffff16da9467", + "coverage_fingerprint": "2d6437f9e53e25eef528460c374bcffade0f74a0105aaebbf7713fcc2132ed27", "official_opcodes": 608, "parse_err_count": 0, - "runtime_verified_forms": 62, - "supported_forms": 452, + "runtime_verified_forms": 64, + "supported_forms": 457, "unique_forms": 911, "unique_ops": 487, - "unsupported_forms": 414, + "unsupported_forms": 409, "encoder_opcodes": 444, "encoder_forms": 1397, "encoder_opcodes_observed_in_corpus": 393, @@ -154,14 +154,14 @@ }, "arm64": { "context_forms": 45, - "coverage_fingerprint": "816994965e8272f2528099ddb023f6656ffb6b26d4739a4b23b56940da4f1cdd", + "coverage_fingerprint": "b41c8147185ffe1f767d123673a31561927f56ec6e18e4a715a631fac898e025", "official_opcodes": 604, "parse_err_count": 0, - "runtime_verified_forms": 62, - "supported_forms": 454, + "runtime_verified_forms": 64, + "supported_forms": 459, "unique_forms": 945, "unique_ops": 487, - "unsupported_forms": 446, + "unsupported_forms": 441, "encoder_opcodes": 444, "encoder_forms": 1402, "encoder_opcodes_observed_in_corpus": 393, @@ -231,14 +231,14 @@ }, "arm64": { "context_forms": 47, - "coverage_fingerprint": "c8291a1d518d8e1651439e445eaad77da93fef4adc9fa94ebc95625086db8d84", + "coverage_fingerprint": "04daf93aacdc190ab87a254de0ebf56cf726b2538813d66f6f0a17d3f3ab5119", "official_opcodes": 606, "parse_err_count": 0, - "runtime_verified_forms": 62, - "supported_forms": 454, + "runtime_verified_forms": 64, + "supported_forms": 459, "unique_forms": 947, "unique_ops": 488, - "unsupported_forms": 446, + "unsupported_forms": 441, "encoder_opcodes": 444, "encoder_forms": 1444, "encoder_opcodes_observed_in_corpus": 394, @@ -308,14 +308,14 @@ }, "arm64": { "context_forms": 47, - "coverage_fingerprint": "2b989fc1d29f7bf5ad0ea040759c6d90cd350c0819de472a21d8080730a18200", + "coverage_fingerprint": "ee873d61168b2b73f55a14753d18a16766f9cb4942a317582a836ec957f19146", "official_opcodes": 606, "parse_err_count": 0, - "runtime_verified_forms": 62, - "supported_forms": 455, + "runtime_verified_forms": 64, + "supported_forms": 460, "unique_forms": 948, "unique_ops": 488, - "unsupported_forms": 446, + "unsupported_forms": 441, "encoder_opcodes": 445, "encoder_forms": 1445, "encoder_opcodes_observed_in_corpus": 394, @@ -385,14 +385,14 @@ }, "arm64": { "context_forms": 47, - "coverage_fingerprint": "2b989fc1d29f7bf5ad0ea040759c6d90cd350c0819de472a21d8080730a18200", + "coverage_fingerprint": "ee873d61168b2b73f55a14753d18a16766f9cb4942a317582a836ec957f19146", "official_opcodes": 606, "parse_err_count": 0, - "runtime_verified_forms": 62, - "supported_forms": 455, + "runtime_verified_forms": 64, + "supported_forms": 460, "unique_forms": 948, "unique_ops": 488, - "unsupported_forms": 446, + "unsupported_forms": 441, "encoder_opcodes": 445, "encoder_forms": 1445, "encoder_opcodes_observed_in_corpus": 394, @@ -462,14 +462,14 @@ }, "arm64": { "context_forms": 47, - "coverage_fingerprint": "8d90049669c26eeda4a3671b56da2eaceb99276e11cabe6066067b41f3ef9be2", + "coverage_fingerprint": "c7188c751d36323903dce2248b35093cd5aeb384ce4f6a5eb0e57b982ac640e5", "official_opcodes": 607, "parse_err_count": 0, - "runtime_verified_forms": 62, - "supported_forms": 455, + "runtime_verified_forms": 64, + "supported_forms": 460, "unique_forms": 949, "unique_ops": 489, - "unsupported_forms": 447, + "unsupported_forms": 442, "encoder_opcodes": 446, "encoder_forms": 1447, "encoder_opcodes_observed_in_corpus": 395, @@ -539,14 +539,14 @@ }, "arm64": { "context_forms": 47, - "coverage_fingerprint": "53b31063476d8a0ac4302c43b05620049ff67be89c346cccd1c61ad71b71d0b1", + "coverage_fingerprint": "b71da01b52530fd1222f22169e5838c673f7908d45f3124b8dd76cf0cd9a59a1", "official_opcodes": 613, "parse_err_count": 0, - "runtime_verified_forms": 62, - "supported_forms": 455, + "runtime_verified_forms": 64, + "supported_forms": 460, "unique_forms": 955, "unique_ops": 495, - "unsupported_forms": 453, + "unsupported_forms": 448, "encoder_opcodes": 450, "encoder_forms": 1451, "encoder_opcodes_observed_in_corpus": 401, @@ -616,14 +616,14 @@ }, "arm64": { "context_forms": 47, - "coverage_fingerprint": "4d297d36051af801c65e07a4010d3d07a8e081f4040d46ecadf894e19adbf451", + "coverage_fingerprint": "5e13a58ed69a0c575affe87e88a65796c217d0a4e7acfdf5f2f3a7c7455d34be", "official_opcodes": 1417, "parse_err_count": 0, - "runtime_verified_forms": 62, - "supported_forms": 457, + "runtime_verified_forms": 64, + "supported_forms": 462, "unique_forms": 1980, "unique_ops": 1281, - "unsupported_forms": 1476, + "unsupported_forms": 1471, "encoder_opcodes": 1253, "encoder_forms": 2964, "encoder_opcodes_observed_in_corpus": 1187,